Sin*_*ble 7 sqlite ruby-on-rails ruby-on-rails-3.2
使用Rails 3.2.9
我试图获取与没有所有者的组织关联的项目列表.
我能够使用下面的数据列表,但对我来说似乎很难看.有一个更好的方法吗?
Items.all(:select => "items.id, items.name",
:joins => "INNER JOIN organizations on items.organization_id = organizations.id",
:conditions => "NOT EXISTS (select * from items k JOIN items_owners on items.id = items_owners.item_id) and items.organization_id = 1")
Run Code Online (Sandbox Code Playgroud)
表设置:
所有者:
项目:
items_owners:
组织:
楷模:
class Organization < ActiveRecord::Base
attr_accessible :name
has_many :items
end
class Item < ActiveRecord::Base
attr_accessible :description, :name, :owner_ids, :organization_id
has_many :items_owner
has_many :owners, :through => :items_owner
belongs_to :organization
end
class Owner < ActiveRecord::Base
attr_accessible :name
has_many :items_owner
has_many :items, :through => :items_owner
end
class ItemsOwner < ActiveRecord::Base
attr_accessible :owner_id, :item_id
belongs_to :item
belongs_to :owner
end
Run Code Online (Sandbox Code Playgroud)
编辑:删除
.all,添加references和添加使用arel_table
Items.joins(:organization).includes(:owners).references(:owners).
where('owners.id IS NULL')
Run Code Online (Sandbox Code Playgroud)
如果你想同时使用includes:
Items.includes(:organization, :owners).references(:organization, :owners).
where('organisations.id IS NOT NULL AND owners.id IS NULL')
Run Code Online (Sandbox Code Playgroud)
正如@Dario Barrionuevo写的那样,它应该是belongs_to:Item in organization
使用arel_table在第一个例子:
Items.joins(:organization).includes(:owners).references(:owners).
where(Owner.arel_table[:id].eq(nil))
Run Code Online (Sandbox Code Playgroud)
在Rails 5中(来自@aNoble的评论):
Items.joins(:organization).left_joins(:owners).
where(Owner.arel_table[:id].eq(nil))
Run Code Online (Sandbox Code Playgroud)
但是includes如果应该在代码中引用关系,则仍然可以使用,以避免额外的读取.
有多种方法可以在 Rails 5、6 中实现 NOT EXISTS:
我突然想到了 4 种方法,但我似乎记得有 7 种。无论如何,这是一个切线,但可能会给你一些更适合你的用例的想法。
我发现使用 NOT IN 方法对于我的团队来说是最容易创建和维护的。我们的目标是避免 arel、支持所有者表中的 WHERE 子句(例如:admin 所有者)以及支持多个级别的 Rails :through。
Items.where.not(id: Items.joins(:owners).select(:id))
.select(:id, :name)
Items.where.not(id: Items.joins(:items_owners).select(:id))
.select(:id, :name)
Items.where.not(id: ItemOwners.select(:item_id))
Run Code Online (Sandbox Code Playgroud)
我们使用第一个,但这些示例应该按照从最不优化到最佳的顺序排列。也是按照对模型的了解从最少到最多的顺序。
| 归档时间: |
|
| 查看次数: |
9783 次 |
| 最近记录: |