Ransacker断言多个关联

时间:2014-06-04 10:10:26

标签: ruby-on-rails ransack

我有一个案例,我有一个名为Event的模型:  * has_one primary_day  * has_one backup_day  * has_one emergency_day

在每个has_one关联中,有一组布尔字段相同,例如 approved_legal,approved_malfunction,approved_costs等

在我的搜索表单中 - 我不想单独搜索每个关联以查找相同的字段。

例如我不想这样做:

<%= f.check_box :primary_day_approved_legal_true %>

对于每个字段,因为它太冗长而我想要这样做:

<%= f.check_box :approved_legal_true %> 

将整理所有关联,并在所有has_one关联中返回approved_legal为true的事件。

我已经尝试了一些不同的方法来解决这个问题,但我无法让它工作,所以我认为我想要做的事情目前是不可能的。你能否证实我的理论,或者让我知道如果确实有可能如何实现它?

作为参考,我尝试了以下内容:

1。事件模型中的自定义搜索者

由于我很乐意使用现有的真实谓词,我想只需添加一个返回我想要的ransacker就可以了。但它似乎不是例如

ransacker :created_at do |parent|
  Arel.sql('select * from events inner join on primary_days .......')
end

这个搜索者似乎总是从添加的模型中选择一个。所以我不能使用联接到关联。似乎ransacker必须返回与其相关的模型上的现有数据库列。因此,出于同样的原因,我没有提出可以使这种方法起作用的Arel代码。尽管尝试创建一个Arel表来表示关联,然后尝试在arel中进行连接 - 但结果总是相同的 - 在ArelSelectManager上没有这样的方法eq。

例如

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

2。使用命名范围和问题61中的范围补丁 - https://gist.github.com/RohanM/5350768

我将代码放在initializers / ransack.rb中,然后:

型号:

scope_ransackable :approved_legal
scope :approved_legal_scope, -> { 
  Event.joins(:primary_day).where(:primary_days: {approved_legal: true}) 
}

控制器

Event.search_with_scopes(params[q])

查看

<%= f.check_box(:approved_legal_scope)%>

但这只是导致错误,说在Ransack搜索对象上找不到approved_legal_scope方法

非常感谢任何指向正确方向的指针。感谢。

1 个答案:

答案 0 :(得分:0)

我已经设法通过链接范围与前Rails 5黑客来实现这一目标。

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

在Rails 5中发布此功能时,where_values.join(' OR ')可以替换为where().or.where()