9
votes

Ruby: Nils dans une déclaration de si

J'ai le code rubis très laids suivant dans une application Rails, je travaille sur:

if params[:search][:tags_name_in].present?


1 commentaires

Une note sur la réponse que je choisis: Dans mon application, il n'est pas important si cette condition renvoie nil ou false , pas plus important que : tags_name_in Ne soyez pas vide, j'ai juste besoin de tester si : tags_name_in est défini sans élever une erreur. Donc, pour ma situation, j'aime le défini? Approche comme indiqué par AYD. Cependant, je pense que Mike Lewis approche peut être plus utile pour d'autres personnes ayant besoin d'éviter de transmettre une valeur nulle dans leur état. Alors, veuillez regarder à la fois les réponses et décider si cela compte dans votre situation.


6 Réponses :


6
votes

parames sera toujours défini, de sorte que vous puissiez supprimer cela.

Pour réduire la quantité de code que vous pouvez faire xxx

si paramètres [: recherche ] n'est pas défini, la condition sera courte et retourner nil .


2 commentaires

J'ai édité de l'indiquer son retour nil , pas false .


Vous supposez que ce code est dans un contrôleur de rails. À l'intérieur d'une classe, les paramètres peuvent être indéfinis ou nul.



0
votes

Je finis généralement à faire quelque chose comme ceci:

if params[:search] && params[:search][:tags_name_in] ...


0 commentaires

4
votes

Vous pouvez utiliser And et pour cela. Il gère cette situation exacte:

Si les params [: recherche] .and [: tags_name_in] .andand.present?


2 commentaires

C'est un joyau très cool, merci pour la pointe!


+1 Si seulement tout le monde utilisait et et dans ces cas (même si je préfère écrire l'équivalent eck's "peut-être") au lieu de conditionnels et de plus de conditionnels (ou de laid "essayer")



3
votes

haha, si vous voulez être terrible et soinyyyypatch nil: xxx

Je recommanderais un court-circuité si comme les autres réponses suggèrent, cependant.


1 commentaires

Pourquoi est-ce mauvais? Me semble assez bon.



11
votes

Si vous essayez simplement de voir si c'est défini pourquoi ne pas le garder simple et utiliser le défini? fonctionner?

if defined?(params[:search][:tags_name_in])


7 commentaires

Cela n'est pas équivalent au code qu'il a initialement demandé concernant. défini? retournera true si une variable a été initialisée, même si elle est définie sur nil . Present? Vérifie à l'aide de vide? , donc nil retournera false.


Bien sûr, mais la question dit qu'il demande simplement s'il a été défini ou non - lequel cela fera.


C'est la réponse la plus propre, il se trouve aussi mal.


alors clarifiante sur la question alors - cherchez-vous défini ou non nul?


OK - Une fois les tests dans mon cas particulier défini fonctionnent parfaitement. Il n'y a pas de situation dans mon application où: tags_name_in peut être défini et nul - mais même s'il a été défini et que la nul qui ne soulève aucune erreur, rien n'arrive (qui est le comportement souhaité). Donc, j'aime cette approche pour ma situation.


@Andrew si params [: recherche] [: tags_name_in] est nul, défini? ne lancera aucune erreur, il retournera la chaîne "variable locale" ou de ce type , qui, à un si déclaration est vrai. Ce n'est pas parce que cela va travailler en ce moment, pour vous, ne fait pas une bonne solution. Le point est que le comportement de défini? n'est pas immédiatement évident ni intuitif, et à l'avenir, vous ou la personne qui prenant votre code peut être mal piqué. L'utilisation de cette approche sacrifie la maintenabilité afin d'économiser 9 caractères.


L'autre problème est que d'utiliser cette valeur, vous devrez écrir cette chaîne de symboles et de crochets, créant ainsi un deuxième point de défaillance et enfreindre le sec.



4
votes

Vous avez de nombreux choix qui retourneront la valeur de param 'params [: recherche] [: tags_name_in] code> ou nil code> si params [: recherche] code > est nil code>.

clair mais long: p> xxx pré>

utilisant essayer code> (à partir de actif_support Code>): p> xxx pré>

à l'aide de sauvetage: p> xxx pré>

utilisant Fetch code>: P >

def deal_with_tags
  MyModel.where :tags => params.fetch(:search){ return }[:tags_name_in]
end


3 commentaires

+1. J'étais sur le point de poster le essayer et Fetch solution. J'ai cessé d'utiliser en ligne sauvetage après avoir trouvé le coût de la manipulation des exceptions dans Ruby.


La méthode de récupération semble très utile, je vais le regarder et je pourrais peut-être l'utiliser à plusieurs endroits!


OP doit traiter des paramètres elles-mêmes! Cette réponse lancerait toujours des erreurs dans ce cas.