Rails has_many con nombre de alias

186

En mi modelo de usuario podría tener:

has_many :tasks

y en mi modelo de tarea:

belongs_to :user

Luego, suponiendo que la clave externa 'user_id' estuviera almacenada en la tabla de tareas, podría usar:

@user.tasks

Mi pregunta es, ¿cómo declaro la relación has_many de tal manera que pueda referirme a las tareas de un usuario como:

@user.jobs

... o ...

@user.foobars

Gracias un montón.

doctor naranja
fuente
77
Me cansaría de usar Task como nombre de clase: es una palabra reservada de Rails y puede causar problemas extraños en el futuro: reservedwords.herokuapp.com
Joshua Pinter

Respuestas:

362

Dale una oportunidad a esto:

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

Tenga en cuenta que :asse usa para asociaciones polimórficas .

Sam Azafrán
fuente
1
Gracias por incluir también la clave externa: resolvió mi problema similar pero diferente.
Niels Abildgaard
44
¿Esto necesita algo especial en el lado de la tarea o es lo belongs_tosuficiente?
estrella brillante
1
FYI: esto también funciona para asociaciones has_and_belongs_to_many, solo que no hay necesidad de la pieza "Foreign_key"
David Moritz
55

También podría usarlo alias_attributesi aún desea poder referirse a ellos como tareas también:

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

  has_many :tasks
end
Pwnrar
fuente
3

Para completar la respuesta de @ SamSaffron:

Se puede usar class_namecon foreign_keyo inverse_of. Personalmente prefiero el declarativo más abstracto, pero en realidad es solo cuestión de gustos:

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

y debe asegurarse de tener el belongs_toatributo en el modelo secundario:

class BlogPostImage
  belongs_to :blog_post
end
Ghis
fuente
0

Si usa has_many through y quiere un alias:

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

Podrías hacer esto de dos maneras diferentes. Una es usando "como"

has_many :tasks, :as => :jobs

o

def jobs
     self.tasks
end

Obviamente, el primero sería la mejor manera de manejarlo.

Brent Kirby
fuente
Gracias, eso suena perfecto. Desafortunadamente esto no funcionó: MODELO DE USUARIO: has_many: tareas,: as =>: created_tasks CONTROLADOR: @created_tasks = @ user.created_tasks ----- NoMethodError en TasksController # index método indefinido `created_tasks 'para # <Usuario: 0xb6050b5c>
doctororange el
44
El segundo método es realmente bastante útil para crear un alias de la asociación.
jpgeek
Esto no parece ser apropiado, como dijo Sam, ya que: es para asociaciones polimórficas.
Michael K Madison