Skip to content

Filter on joined table

Kim Røen edited this page Sep 16, 2015 · 2 revisions

Problem: You wish to filter on a column in a joined table. This may be in another resource, or simply in a one to one relationship on the model.

Solution: By default the filters append a where condition to the relation with the filter name matching a column in the primary relation. By overriding the apply_filter method you can control how the filter is applied.

An example where the User model joins in a user_extra table using a default scope:

class User < ActiveRecord::Base default_scope { joins("LEFT JOIN user_extras ON user_extras.user_id = users.id") } end class UserResource < JSONAPI::Resource #phone_number comes from the user_extras table attributes :name, :email, :phone_number, :notes filters :name, :email, :phone_number class << self def apply_filter(records, filter, value, options) case filter when :phone_number records.where('user_extras.phone_number = ?', value) else return super(records, filter, value) end end end end

Note that it's also possible to have the resource perform the inclusion of the user_extras using the records method instead of using the default_scope on the model:

class User < ActiveRecord::Base end class UserResource < JSONAPI::Resource #phone_number comes from the user_extras table attributes :name, :email, :phone_number, :notes filters :name, :email, :phone_number class << self def records(options = {}) _model_class.joins(:user_extras) end def apply_filter(records, filter, value, options) case filter when :phone_number records.where('user_extras.phone_number = ?', value) else return super(records, filter, value) end end end end
Clone this wiki locally