2010-11-09 23 views
1

J'ai un modèle Rails appelé Person qui a des colonnes de table de base de données pour prénom et nom_famille. J'ai également défini une méthode full_name pour renvoyer le prénom et le nom de famille combinés de l'instance.Comment renvoyer un tableau d'attributs définis via une méthode de modèle Rails, ainsi que les attributs de la table de base de données?

Existe-t-il un moyen de renvoyer un tableau, un hachage ou un objet avec prénom, nom_famille et nom_complet?

Voici le code que j'ai:

#person.rb 
class Person < ActiveRecord::Base 
    validates_presence_of :first_name, :last_name 

    def full_name 
     self.first_name + " " + self.last_name 
    end 
end 

Voici ce que j'ai essayé dans la console Rails:

ruby-1.8.7-p302 > person = Person.new({:first_name=>"Bruce", :last_name=>"Wayne"}) 
=> #<Person id: nil, first_name: "Bruce", :last_name: "Wayne", created_at: nil, updated_at: nil> 

ruby-1.8.7-p302 > person.save! 
=> true 

ruby-1.8.7-p302 > Person.last 
=> #<Person id: 1, first_name: "Bruce", :last_name: "Wayne", created_at: "2010-11-09 22:53:14", updated_at: "2010-11-09 22:53:14"> 

Est-il possible d'obtenir quelque chose retourné comme ceci:

ruby-1.8.7-p302 > Person.last 
=> #<Person id: 1, first_name: "Bruce", :last_name: "Wayne", :full_name: "Bruce Wayne", created_at: "2010-11-09 22:53:14", updated_at: "2010-11-09 22:53:14"> 

Ou peut-il seulement renvoyer des valeurs de la base de données?

Finalement, je voudrais être en mesure d'appeler Person.all pour retourner un tableau de hachages qui comprend également full_name.

Merci à l'avance!

Répondre

1

Les first_name et last_name sont des attributs DB qui sont imprimés dans la méthode inspect. Si vous voulez accéder au full_name, appelez full_name sur l'objet utilisateur.

User.last.full_name 

Donc, si vous voulez un hachage des utilisateurs full_name comme la clé:

@users = {} 
User.all.each{|u| @users[u.full_name] = u} 

Modifier 1

L'appel User.last retourne un objet User. Ce qui est imprimé dans la console dépend de l'implémentation de la méthode d'inspection sur l'objet. Dans le cas d'ActiveRecord, les attributs de base de données sont imprimés.

Si vous avez besoin du nom complet, vous devez appeler la méthode full_name sur l'objet Utilisateur renvoyé.

Je ne comprends toujours pas ce que vous essayez de faire.

Modifier 2

u = User.last 
[u.full_name, u.age, u.phone] # array 
{:full_name => u.full_name, :age => u.age, :phone => u.phone } #hash 

Edit 3

Si vous souhaitez obtenir un format JSON sur un objet procédez comme suit

u.to_json(:methods => [:full_name]) 

Référez-vous au to_jsondocumentation pour plus de détails.

Modifier 4

La méthode to_json pour vous et a includeexclude options pour sélectionner les attributs dont vous avez besoin. La méthode to_json vous donne un contrôle total sur la sélection des données. Reportez-vous au lien de la documentation ci-dessus pour plus de détails.

u.to_json(:methods => [:full_name], :include => [:first_name, :last_name]) 

Si vous devez inclure des attributs supplémentaires, les ajouter au tableau :include dans l'exemple ci-dessus.

Edit 5

Pour utiliser ceci avec respond_with, procédez comme suit:

respond_with(@users, :methods => [:full_name], 
        :include => [:first_name, :last_name]) 
+0

Merci, mais existe-t-il un moyen de renvoyer les trois: prénom, nom_famille et nom complet dans un hachage? Aucun de vos exemples ne le fait quand j'ai essayé votre code. – Chanpory

+0

Que voulez-vous dire par un hachage? Développez votre question pour inclure un résultat attendu. –

+0

S'il vous plaît voir le troisième exemple dans la question: '# ' ... prénom, nom et nom complet sont renvoyés. – Chanpory

0

Après avoir frappé ma tête, il ressemble à un moyen d'obtenir un tableau de tous les DB attributs plus le full_name attribut est à faire:

person = Person.last.attributes 
person["full_name"] = Person.last.full_name 

Dans la console ce retournera quelque chose comme:

=> {"first_name" => "Bruce", "created_at" => Tue Nov 09 22:53:14 UTC 2010, "updated_at" => Tue Nov 09 22:53:14 UTC 2010", "id" => 58, "last_name" => "Wayne", "full_name" => "Bruce Wayne"} 
0

Vous pouvez le faire pour une seule personne dans une ligne avec:

Person.first.instance_eval { attributes.merge("full_name" => full_name)} 

En ce qui concerne votre désir de revenir Person.all et hash, pourquoi voudriez-vous ce comportement? Par défaut, il retourne un tableau d'instances Person, et je ne recommanderais pas de surcharger une méthode de rails par défaut pour renvoyer un type différent de celui que vous attendez normalement. Si vous voulez ce comportement, j'ajouterais une méthode de classe sur Person, quelque chose comme Person.all_hashes, qui retourne un tableau de hashes pour chaque résultat.

+0

Très utile, je dois admettre que je pensais que les instances de personnes étaient elles-mêmes des tableaux ... , Je ne pouvais pas comprendre pourquoi je ne pouvais pas insérer une autre valeur dans l'instance de Person. Désolé, très nouveau sur Ruby on Rails! – Chanpory

+0

@GeekActive, puisque vous avez trouvé la réponse utile et l'avez acceptée, vous devriez probablement la mettre aussi à votation. – Zabba

+0

Je n'ai pas assez de points de réputation pour l'augmenter :-( – Chanpory