#3 Find Through Association
In this Rails application we have a Project
model which has_many
tasks:
class Project < ActiveRecord::Base has_many :tasks end
and a Task
model which belongs_to
a project:
class Task < ActiveRecord::Base belongs_to :project end
In the project’s controller method is a show
action. We want to display a Project
, along with all of the Task
s in the project which are incomplete. To do this we perform a find
on the Task
model to find tasks where the project_id
matches the Project
’s id and where the complete
field is false
:
class ProjectsController < ApplicationController def show @project = Project.find(params[:id]) @tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false]) end end
There is a better way to do this. A find
can be performed through an association. The line above that finds that tasks can be changed from
@tasks = Task.find(:all, :conditions => ['project_id = ? AND complete = ?', @project.id, false])
to
@tasks = @project.tasks.find(:all, :conditions => [complete = ?', false])
This means that the project_id
can be removed from the find
as it’s already specified by doing the find through the project’s tasks.
This line can be shortened even more by using a dynamic find method in the scope of the project model to this:
@tasks = @project.tasks.find_all_by_complete(false)