Rails has_many avec un nom d'alias

192

Dans mon modèle utilisateur, je pourrais avoir:

has_many :tasks

et dans mon modèle de tâche:

belongs_to :user

Ensuite, en supposant que la clé étrangère 'user_id' soit stockée dans la table des tâches, je pourrais utiliser:

@user.tasks

Ma question est la suivante: comment déclarer la relation has_many de sorte que je puisse faire référence aux tâches d'un utilisateur comme suit:

@user.jobs

... ou ...

@user.foobars

Merci beaucoup.

docteurorange
la source
7
Je serais fatigué d'utiliser Task comme nom de classe - c'est un mot réservé à Rails et pourrait causer d'étranges problèmes sur la route: reservedwords.herokuapp.com
Joshua Pinter

Réponses:

374

Essayez ceci:

has_many :jobs, foreign_key: "user_id", class_name: "Task"

Notez que cela :asest utilisé pour les associations polymorphes .

Sam Safran
la source
1
Merci d'avoir également inclus la clé étrangère - résolu mon problème similaire mais différent.
Niels Abildgaard
4
Cela a-t-il besoin de quelque chose de spécial du côté des tâches ou est-ce que l'habituel est belongs_tosuffisant?
étoile brillante
1
FYI: cela fonctionne aussi pour has_and_belongs_to_many associations, seulement pas besoin de la pièce "Foreign_key"
David Moritz
59

Vous pouvez également utiliser alias_attributesi vous souhaitez toujours pouvoir y faire référence en tant que tâches:

class User < ActiveRecord::Base
  alias_attribute :jobs, :tasks

  has_many :tasks
end
Pwnrar
la source
3

Pour compléter la réponse de @ SamSaffron:

Vous pouvez utiliser class_namesoit avec foreign_keyou inverse_of. Personnellement, je préfère le déclaratif plus abstrait, mais ce n'est vraiment qu'une question de goût:

class BlogPost
  has_many :images, class_name: "BlogPostImage", inverse_of: :blog_post  
end

et vous devez vous assurer que vous avez l' belongs_toattribut sur le modèle enfant:

class BlogPostImage
  belongs_to :blog_post
end
Ghis
la source
3

Si vous utilisez has_many through et souhaitez créer un alias:

has_many :alias_name, through: model_name, source: initial_name
A. Askarov
la source
-61

Vous pouvez le faire de deux manières différentes. La première consiste à utiliser "comme"

has_many :tasks, :as => :jobs

ou

def jobs
     self.tasks
end

De toute évidence, le premier serait la meilleure façon de le gérer.

Brent Kirby
la source
Merci, cela semble parfait. Malheureusement, cela n'a pas fonctionné: MODÈLE D'UTILISATEUR: has_many: tasks,: as =>: created_tasks CONTROLLER: @created_tasks = @ user.created_tasks ----- NoMethodError dans TasksController # index méthode non définie `created_tasks 'for # <User: 0xb6050b5c>
doctororange
4
La deuxième méthode est en fait très utile pour créer un alias de l'association.
jpgeek
Cela ne semble pas approprié, comme Sam l'a dit, car: est pour les associations polymorphes.
Michael K Madison