-
Notifications
You must be signed in to change notification settings - Fork 332
Search on second order association
scambra edited this page Sep 15, 2010
·
4 revisions
Let’s suppose a models relationship as follows:
class Employee < ActiveRecord::Base
has_many :jobs
has_many :tasks, :through => :jobs
end
class Job < ActiveRecord::Base
belongs_to: employee
has_many :tasks
end
class Task < ActiveRecord::Base
belongs_to: job
endA common need is displaying the ‘employee’ associated to each ‘task’ in the ‘tasks’ list view, and also allowing search based on ‘employee’. Following code implements it.
First of all define a ‘employee’ field for ‘task’ model (note that there could be no ‘job’ associated to current ‘task’ model, or no ‘employee’ associated to its ‘job’):
class Task < ActiveRecord::Base
[...]
delegate :employee, :to => :job, :allow_nil => trueAdd the required “magic” to ‘tasks’ controller:
- Add ‘employee’ to the search fields.
- Set the table/column or SQL for the ‘employee’ search.
- Set an include in ‘job’ field.
class TasksController < ApplicationController
[...]
config.search.columns << :employee
config.columns[:employee].search_sql = "employees.name"
config.columns[:employee].includes = {:job => :employee}
config.columns[:employee].search_ui = :string # optional
config.columns[:employee].options[:string_comparators] = true # optional
endThe SQL added during a ‘employee’ search by the above code looks as follows:
[...] LEFT OUTER JOIN `employees` ON `employees`.id = `jobs_tasks`.employee_id WHERE (((LOWER(employees.name) LIKE '%[...]%')))And voilá, the ‘tasks’ list view displays the ‘employee’ for each row and also allows search based on its name.