Как отправить логический параметр в Rails?
я отправляю параметр show_all
со значением true
. Это значение не связано с моделью.
мой контроллер присваивает этот параметр переменной экземпляра:
@show_all = params[:show_all]
однако, @show_all.is_a? String
и if @show_all == true
всегда терпит неудачу.
какие значения Rails анализирует как булевы? Как я могу явно указать, что мой параметр является логическим, а не строкой?
9 ответов:
Я хотел прокомментировать ответ zetetic, но поскольку я еще не могу этого сделать, я опубликую это в качестве ответа.
Если вы используете
@show_all = params[:show_all] == "1"
затем вы можете удалить
? true : false
, потому чтоparams[:show_all] == "1"
сам оператор будет оцениваться как true или false и, следовательно, тернарный оператор не нужен.
обновление: рельсы 5:
ActiveRecord::Type::Boolean.new.deserialize('0')
обновление: Rails 4.2 имеет открытый API для этого:
ActiveRecord::Type::Boolean.new.type_cast_from_user("0") # false
ПРЕДЫДУЩИЙ ОТВЕТ:
ActiveRecord поддерживает список представлений для true / false в https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/column.rb
2.0.0-p247 :005 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean("ON") 2.0.0-p247 :006 > ActiveRecord::ConnectionAdapters::Column.value_to_boolean("F")
Это не является частью публичного API Rails, поэтому я завернул его в вспомогательный метод:
class ApplicationController < ActionController::Base private def parse_boolean(value) ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value) end end
и добавил базовый тест:
class ApplicationControllerTest < ActionController::TestCase test "parses boolean params" do refute ApplicationController.new.send(:parse_boolean, "OFF") assert ApplicationController.new.send(:parse_boolean, "T") end end
этот вопрос довольно старый, но так как я столкнулся с этой проблемой пару раз, и мне не понравилось ни одно из предложенных решений, я сам взломал что-то, что позволяет использовать несколько строк для правда например, "да", "on", " t " и наоборот для false.
Monkey исправляет строку класса и добавляет метод для преобразования их в boolean, и помещает этот файл в
/config/initializers
как предложено здесь: обезьяна латая в рельсах 3class String def to_bool return true if ['true', '1', 'yes', 'on', 't'].include? self return false if ['false', '0', 'no', 'off', 'f'].include? self return nil end end
обратите внимание, что если значение не является ни одним из допустимых для true или false, то оно возвращает nil. Это не то же самое искать
?paid=false
(вернуть все записи не оплачены) чем?paid=
(Я не указываю, должен ли он быть оплачен или нет-так что отбросьте это).затем, следуя этому примеру, логика в вашем контроллере будет выглядеть так:
Something.where(:paid => params[:paid].to_bool) unless params[:paid].try(:to_bool).nil?
Это довольно аккуратно, и помогает держать контроллеры/модели чистой.
@show_all = params[:show_all] == "1" ? true : false
Это должно работать хорошо, если вы передаете значение из флажка -- отсутствующий ключ в хэше генерирует nil, который оценивается как false в условном.
EDIT
Как указал здесь, тернарный оператор не нужен, так что это может быть просто:
@show_all = params[:show_all] == "1"
вы можете изменить свое утверждение равенства на:
@show_all == "true"
Если вы хотите, чтобы он был логическим, вы можете создать метод в классе string для преобразования строки в логическое значение.
Я думаю, что самое простое решение-проверить "булевы" параметры против их строкового представления.
@show_all = params[:show_all] if @show_all.to_s == "true" # do stuff end
независимо от того, предоставляет ли Rails параметр в виде строки "true" или "false" или фактического TrueClass или FalseClass, этот тест всегда будет работать.
вы можете конвертировать все ваши логические параметры в реальные логические значения следующим образом:
%w(show_all, show_featured).each do |bool_param| params[bool_param.to_sym] = params[bool_param.to_sym] == "true" end
в этом решении нулевые параметры станут ложными.
другой подход заключается в передаче только ключа без значения. Хотя с помощью
ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
довольно аккуратно, может возникнуть ситуация, когда присвоение значения ключу param является избыточным.рассмотрим следующий: В моем представлении индекса продуктов по умолчанию я хочу показать только ограниченную коллекцию продуктов (например, те, которые находятся на складе). То есть если я хочу вернуть все продукты, я могу отправить
myapp.com/products?show_all=true
и типизировать