I have a case where I have a model called Event which: * has_one primary_day * has_one backup_day * has_one emergency_day
In each of the has_one associations there a group of boolean fields that are the same eg approved_legal,approved_malfunction,approved_costs etc
In my search form - I don't want to search each association individually for those same fields.
eg I don't want to do this:
<%= f.check_box :primary_day_approved_legal_true %>
for each of the fields as it's too verbose instead I want to do this:
<%= f.check_box :approved_legal_true %>
which will collate all the associations and return Events that have approved_legal true across all the has_one associations.
I have tried a few different approaches to solving this but I can't get it to work so I assume that what I want to do is currently not possible. Could you confirm my theory or let me know how it could be achieved if it is indeed possible?
For reference I have tried the following:
Since I'm happy to use the existing true predicate I thought just adding in a ransacker that returned what I wanted would be possible. But it seems not eg
ransacker :created_at do |parent|
Arel.sql('select * from events inner join on primary_days .......')
end
this ransacker seems to alway start with a select on the Model it was added to. So I cannot use a join to the associations. It seems the ransacker must return an existing database column on the model it's related to. So for the same reason there was not Arel code I could come up with that would make this approach work. Despite trying to create an Arel table to represent the associations and then trying to do the join in arel - but the result was always the same - no such method eq on ArelSelectManager.
eg
ransacker :created_at do |parent|
primary_days = Arel::Table.new(:primary_days)
events = parent.table
events.join(primary_days).on(events[:id].eq(primary_days[:event_id]))
end
I put the code in the initializers/ransack.rb and then:
Model:
scope_ransackable :approved_legal
scope :approved_legal_scope, -> {
Event.joins(:primary_day).where(:primary_days: {approved_legal: true})
}
Controller
Event.search_with_scopes(params[q])
View
<%= f.check_box(:approved_legal_scope)%>
But this just resulted in an error saying that approved_legal_scope method was not found on Ransack Search object
Any pointer in the right direction would be very much appreciated. Thanks.
I have managed to achieve this with chaining scopes with a pre-Rails 5 hack.
scope :short_search_scope, ->(search) {
joins(:something)
.where(
unscoped.one_scope(search)
.another_scope(search)
.where_values.join(' OR '))
}
scope :one_scope, -> (search) {
where(approved_legal: true)
}
...
def self.ransackable_scopes(auth_object = nil)
[:short_search_scope]
end
The where_values.join(' OR ')
can be replaced with where().or.where()
when this feature is released in Rails 5.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.