2017-09-11 3 views
0

J'ai un service qui met en place un tableau de Answer objets, chacun contenant une chaîne pour le texte de réponse, un booléen indiquant si c'est la bonne réponse ou non et son id. Ceci est mon code jusqu'à présent:Rails - Vous ne pouvez pas obtenir seulement quelques-uns des attributs pour tous les objets d'un tableau?

@quiz.questions[current_question_index].answers 

Cela fonctionne. Je prends alors ce tableau d'objets de réponse et l'envoie sur un canal ActionCable pour être affiché en tant que boutons - cela fonctionne également.

Mais maintenant, je pense qu'il serait préférable de ne pas envoyer les Answer ensemble des objets (y compris les informations des réponses est correcte), mais seulement id et le titre alors j'ai essayé de changer mon code selon this post:

@quiz.questions[current_question_index].answers.pluck(:id, :title) 

Cela ne fonctionne pas pour moi - tous mes boutons affichent maintenant "undefined". Donc, je l'ai essayé une autre façon selon this post:

@quiz.questions[current_question_index].answers.attributes.slice('id', 'title') 

Maintenant, mes boutons ne sont même pas affichés plus ...

Ce que je veux est un tableau d'objets contenant de l'id 'attributs et 'titre' de mon récupéré Answers.

Quelqu'un peut-il me donner des pointeurs pour résoudre ce problème? Je suis un débutant Rails et j'apprécierais vraiment l'aide.

Répondre

1

Comme vous avez dit answers est un tableau, et la méthode pluck ne sont pas disponibles sur le tableau (il est le AR magic)

Et probablement avec le correctif, vos boutons ont arrêté l'affichage car avant d'avoir un tableau d'objets de réponse, et maintenant vous avez un tableau de hachages avec des clés: id et title.

Vous devriez vérifier l'inspecteur dans votre navigateur (F11 en chrome) pour voir quel type d'erreurs Javascript vous avez et corriger en conséquence.

L'envoi de hachages à la place d'objets complets est une bonne idée, il vous suffit de changer la façon dont vous les utilisez du côté réception.

Edit:

En ce qui concerne les attributs que vous devez faire quelque chose comme ça

@quiz.questions[current_question_index]. 
    answers.map{|answer| answer.attributes.slice('id', 'title') 

Il aura pour effet que vous attendez.

En ce qui concerne "Rails magic". Ce que je voulais dire était ceci: Les Rails n'appellent pas la requête jusqu'au tout dernier moment, mais vous avez un objet Answer::ActiveRecord_Relation qui vous permet d'appeler des méthodes d'enregistrement actives (pluck parmi eux).

Dans votre exemple, vous construisez un tableau de Answers et vous ne pouvez pas appeler pluck sur un tableau - ce n'est tout simplement pas défini.

J'espère que c'est plus clair maintenant.

+0

Ok merci pour l'explication @meta. J'ai donc essayé d'utiliser à nouveau slice et cela me donne un NoMethodError pour 'attributes':/Je pensais que' attributes' était un assistant Rails quand j'ai lu l'autre Stackoverflow, je n'ai pas de modèle ou d'attributs nommés ... – megahra

+0

Et aussi: qu'est ce que le _AR magic_? :) J'ai vérifié le lien, mais je ne comprends pas la différence et pourquoi il n'est pas disponible sur les tableaux (même si je vous crois sur parole). – megahra

+0

J'ai mis à jour ma réponse, s'il vous plaît jeter un oeil – meta

1
question = @quiz.questions[current_question_index] 
answers = question.answers.map { |a| a.attributes.slice('id', 'title') } 

#attributes est une méthode sur une instance de modèle afin que vous ne pouvez pas appeler sur un tableau ou une collection. Il renvoie un hachage avec des clés de chaîne.

Answer.first.attributes 
=> { id: 1, title: 'foo' } 

Si vous voulez même sortie que plumer (un tableau de tableaux) puis utilisez:

.slice('id', 'title').values 

Cependant, l'utilisation d'un hachage (qui associe à un objet JS/JSON) est la meilleure alternative . D'autre part est une méthode ActiveRecord qui fonctionne sur une collection ou une portée puisqu'elle crée une requête SELECT foo, bar FROM baz et renvoie un tableau de tableaux.

Par exemple:

Question.find(1).answers.pluck('id', 'title') 
=> [[1, 'foo'], [2, 'bar']] 
+0

Vous pouvez également utiliser ActiveModel :: Serializers ou jBuilder pour créer JSON à partir de vos modèles. – max