Si tratamos de agregar una tarea desde el navegador nos lanzará un error aunque todos los campos estén validados, esto es por la relación que se hizo la clase pasada (belongs_to :owner
). Las relaciones con belongs_to no pueden quedar vacías.
Para solucionar el problema hay que relacionar el usuario que inició sesión con la tarea pero de manera interna.
El mejor lugar para hacer esta asociación es el controlador tasks_controller.rb, y en el método create del mismo.
Para hacerlo se usa la variable de instancia task que ya existe en el controlador, y se le asigna a su propiedad owner el usuario actual con la variable de entorno current_user. El método current_user es provisto por devise y devuelve la referencia del usuario que inició sesión.
Participant
Creación del modelo Participant: rails g model Participant role:integer user:references task:references
.
Una vez creado el modelo hay que especificar como serán las relaciones con user y task.
En el archivo User.rb agregamos: has_many :participations,class_name: 'Participant'
, pero debido a que esta es una relación intermedia para una asociación de muchos a muchos se puede llegar a las tareas en las cuales el usuario está participando a través del otro método.
has_many :owned_tasks
has_many :participations, class_name: 'Participant'
has_many :tasks, through: :participations
Este nuevo método representa una variación de has_many, la consigna sería que un usuario tiene muchas tareas, pero estas tareas no son las tareas directas, sino a las que se accede a través de participations. El método es: has_many :tasks, through: :participations
.
Ahora hay que aplicar este mismo concepto con las tareas. En este caso se podría decir que las tareas tienen muchos participantes (usuarios).
has_many :participating_users, class_name: 'Participant'
has_many :participants, through: :participating_users, source: :user
Algo que se agregó fue la propiedad source, esto porque se utilizo participants en el has_many y no users, entonce hay que especificar que se trata de el modelo user.
Por último hay que validar que una tarea siempre tenga participantes, esto dentro del model Task:
validates :participating_users, presence: true
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?