mysql - Rails 在不同的动态范围下两次连接同一个表

标签 mysql ruby-on-rails ruby arel

我有一个 Rails 3.0.1 中的应用程序。有一个名为 Books 的表,其中有许多列表。我与列表有条件关联,具体取决于它们是好列表还是坏列表。

#Book.rb
has_many :lists
has_many :good_lists, :foreign_key => 'book_id', :class_name => "List", :conditions => {:id => List.good_list_ids}
has_many :bad_lists, :foreign_key => 'book_id', :class_name => "List", :conditions => {:id => List.bad_list_ids}

目前,条件是在应用程序启动时缓存的,但我希望它是动态的,因为 good_list_idsbad_list_ids 可以更改运行时。我希望能够通过链接连接找到与两个列表关联的书籍。例如,如果 good_lists_ids = [1,2,3]bad_lists_ids = [4,5,6]。我想要获取与至少一个 good_list_ids 和至少一个 bad_list_ids 关联的图书。

Book.joins(:good_lists).joins(:bad_lists)

我知道可以通过从数据库获取记录后应用过滤器来完成。但是有没有办法只在 SQL 中使用 AREL 来做到这一点?

最佳答案

我同意@zapico - 使用范围。而且您必须使用 Lambda,因为 List.good_list_idsList.bad_list_ids 是动态的。

#Book.rb
has_many :lists    
scope :good_lists, -> { joins(:lists).where('lists.id IN (?)', List.good_list_ids) }
scope :bad_lists, -> { joins(:lists).where('lists.id IN (?)', List.bad_list_ids) }

更新

现在您可以获得这些列表中的书籍

# in bad list
Book.bad_lists
# in good list
Book.good_lists
# in both lists (this is intersection! for these lists)
Book.bad_lists.good_lists

如果您想让记录属于 good_list 或 bad_list 那么在我看来最简单的方法是

# join arrays
scope :good_bad_lists, -> { joins(:lists).where('lists.id IN (?)', List.good_list_ids | List.bad_list_ids) }

关于mysql - Rails 在不同的动态范围下两次连接同一个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18662415/

相关文章:

mysql - java.sql.ResultSet.next() 说明

ruby-on-rails - Ruby:不兼容的库版本

ruby - 以深度优先顺序生成数组笛卡尔积的算法

javascript - 为什么 Ruby 包含在内?函数无法按 AngularJS 变量的预期工作?

Python内部数据库使用

PHP 消息表单

MySQL 选择对给定行具有特定值的表的 column_names

javascript - 按 Enter 键进行搜索

ruby-on-rails - 向模型添加新列

ruby - 我在 ruby​​ 1.8 应用程序中使用 ftools,如何使其与 ruby​​ 1.9 兼容