Как отправить логический параметр в 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и типизировать