2010-07-12 3 views
1

Lors de l'extraction de contenu à partir d'une base de données à l'aide d'activerecord, je souhaite récupérer un jeu de résultats personnalisé avec des colonnes spécifiées sur deux tables.Rails 2: jointures et: include resultset

SELECT users.name, users.username, users.age, users.city_id, cities.name as city_name FROM users INNER JOIN cities ON users.city_id = cities.id 

qui serait en AR comme

Users.find(:all, 
    :joins => :cities, 
    :select => "users.name, users.username, users.age, users.city_id, 
     cities.name as city_name") 

Mais cela ne renvoie les résultats de la table utilisateur et pas les résultats de la ville. Je suis sûr à 100% que l'instruction de jointure interne est en cours (que les deux tables sont jointes).

Il semble que l'objet de retour ne possède que les colonnes associées au modèle. Ainsi UserModel aurait seulement les colonnes que la table des utilisateurs a et ne permettra pas d'aller chercher les colonnes de la table des villes même si elles sont spécifiées dans le select.

Devrais-je utiliser: jointures ou: include? Une idée de ce qui se passe?

Répondre

3

Si vous alias le nom de colonne jointe alors objet retourné doit avoir un attribut par le nom d'alias, à savoir

u = User.first(:joins => :cities, 
     :select => "users.*, cities.name AS city_name") 
u.city_name # returns the city_name. 

Dans votre cas, :joins est approprié que :include .

J'ai vérifié dans ma configuration et cela fonctionne pour moi (je suis sur Rails 2.3.8)

1

Dans vos instances renvoyées, si le nom de la colonne est city_name, vous devez utiliser user.city_name. Sinon, si vous utilisez: include, vous demanderiez à ActiveRecord de charger les modèles de villes associés, que vous référenceriez ensuite sous le nom user.city.name.

Pour résumer:

users = User.find(:all, :joins => :cities, :select => "users.name, users.username, users.age, users.city_id, cities.name as city_name") 
users.map(&:city_name) 

users = User.find(:all, :include => :cities) 
users.map(&:city).map(&:name) 
0

vous pouvez utiliser le nom de colonne spécifique dans le tableau de l'utilisateur à la place de « utilisateurs. * » Si vous ne avez pas besoin tous colonne. Je pense que c'est une bonne pratique de programmation.

u = User.first (: => jointures: villes, : sélectionner => "users.name, users.username, users.age, users.city_id, cities.name AS CITY_NAME")

u.city_name # retourne le nom de la ville.