82 votes

Comment envoyer un paramètre booléen dans Rails?

Je soumets un paramètre show_all avec la valeur true . Cette valeur n'est pas associée à un modèle.

Mon contrôleur attribue ce paramètre à une variable d'instance:

 @show_all = params[:show_all]
 

Cependant, @show_all.is_a? String et if @show_all == true échouent toujours.

Quelles sont les valeurs analysées par Rails en tant que booléens? Comment puis-je spécifier explicitement que mon paramètre est un booléen et non une chaîne?

110voto

Wojtek Kruszewski Points 1659

ActiveRecord tient à jour une liste des représentations de vrai/faux dans 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")

Ce n'est pas une partie de Rails' API publique, donc je l'ai enveloppé dans un helper:

class ApplicationController < ActionController::Base
  private

  def parse_boolean(value)
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value)
  end
end

et ajouté un test de base:

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

74voto

Uģis Ozols Points 744

Je voulais faire un commentaire sur la réponse zététique, mais comme je ne peux pas le faire, je vais le poster en tant que réponse.

Si tu utilises

@show_all = params[:show_all] == "1"

alors vous pouvez abandonner ? true : false car l'instruction params[:show_all] == "1" elle-même sera évaluée comme étant vraie ou fausse et qu'un opérateur ternaire n'est donc pas nécessaire.

22voto

ismriv Points 385

Cette question est un peu vieux, mais depuis que je suis tombé sur cette question à quelques reprises, et n'a pas comme l'une des solutions proposées, j'ai programmé moi-même quelque chose qui permet d'utiliser plusieurs chaînes de vrai comme 'oui', 'sur', 't' et le contraire pour de faux.

Monkey patch de la classe String, et ajouter une méthode à les convertir en booléen, et de placer ce fichier dans /config/initializers comme suggéré ici: Monkey Patching dans Rails 3

class 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

Notez que si la valeur n'est pas valide, soit de vrai ou de faux, puis il retourne nil. Ce n'est pas la même à la recherche d' ?paid=false (retourner tous les enregistrements ne sont pas remboursés) que ?paid= (je n'ai pas préciser si il faut le payer ou pas -- donc jeter ce).

Puis, à la suite de cet exemple, la logique de votre contrôleur devrait ressembler à ceci:

Something.where(:paid => params[:paid].to_bool) unless params[:paid].try(:to_bool).nil?

Il est assez soignée, et aide à garder les contrôleurs/modèles propres.

17voto

zetetic Points 29261
 @show_all = params[:show_all] == "1" ? true : false
 

Cela devrait fonctionner correctement si vous transmettez la valeur à partir d'une case à cocher - une clé manquante dans un hachage génère nil, ce qui donne False dans une condition.

MODIFIER

Comme indiqué ici , l'opérateur ternaire n'est pas nécessaire, il peut donc s'agir simplement:

@show_all = params[:show_all] == "1"

4voto

benr75 Points 220

Vous pouvez modifier votre déclaration d'égalité en:

 @show_all == "true"
 

Si vous voulez que ce soit un booléen, vous pouvez créer une méthode sur la classe string pour convertir une chaîne en boolean.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X