我有一个缩小特定类列表的搜索页面,我想要一个可以抓住两个不同条件的OR条件并将它们加在一起,例如,我有类
模型/ party.rb
class Party < ActiveRecord::Base
has_many :invitations
end
模式/ invitation.rb
class Invitation < ActiveRecord::Base
belongs_to :party
end
邀请具有状态属性,该属性将为&#34;拒绝&#34;,&#34;接受&#34;或&#34;未答复&#34;
我想要做的就是抓住所有没有邀请的政党,或任何拥有所有邀请的政党&#34;未得到答复&#34;。
我目前正在做
scope :not_confirmed, lambda { find_by_sql( "SELECT * FROM `parties` INNER JOIN `invitations` ON `invitations`.`party_id` = `parties`.`id` WHERE (invitations.status = 'unanswered') OR (parties.id NOT IN (SELECT DISTINCT(party_id) FROM invitations))" ) }
有效,但由于它没有延迟加载,我无法将其添加到类似查询的方面。
我做了类似
的事情no_invitations.or(no_one_has_answered)
但它不起作用。
我特别不明白在AREL上使用OR的概念,有人可以帮帮忙吗?
编辑:
对于一个非常丑陋但功能性的工作,直到我解决这个问题,这就是我所做的
party.rb
scope :not_confirmed, lambda { joins(:invitations).where( "invitations.status NOT IN (?)", ["accepted", "declined" ] ) }
scope :with_no_invitations, lambda { includes(:invitaions).where( :invitations => { :party_id => nil } ) }
search_controller.rb
@parties = Party.all_the_shared_queries
@parties = ( @parties.not_confirmed + @parties.with_no_invitations).uniq
答案 0 :(得分:2)
查询:
scope :not_confirmed, lambda { find_by_sql( "SELECT * FROM `parties` INNER JOIN `invitations` ON `invitations`.`party_id` = `parties`.`id` WHERE (invitations.status = 'unanswered') OR (parties.id NOT IN (SELECT DISTINCT(party_id) FROM invitations))" ) }
也可以使用布尔代数进行一些转换,转换为arel。但由于只有理论转换,您必须手动验证它。所以:
class Invitation < ActiveRecord::Base
belongs_to :party
scope :non_answered, -> { where(arel_table[:status].not_eq('unanswered')) }
end
class Party < ActiveRecord::Base
has_many :invitations
scope :not_confirmed, -> { not.join(:invitaions).merge(Invitation.non_answered)) }
end
请在此测试并发表评论。
答案 1 :(得分:1)
首先,从问题标签开始,我假设您使用的是Rails3(如果它是Rails4,有更简单的方法可以做到:)
根据您的要求(即抓住所有没有邀请的参与者,或任何拥有所有邀请的参与者&#34;未答复&#34;),这是一种方式这样做(使用范围:无人值守):
派对模特:
class Party < ActiveRecord::Base
has_many :invitations
scope :invitations_answered, -> { joins(:invitations).merge(Invitation.answered) }
scope :unattended, -> { where(arel_table[:id].not_in invitations_answered.pluck(:id)) }
end
邀请模特:
class Invitation < ActiveRecord::Base
belongs_to :party
scope :answered, -> { where(status: ["decline", "accept"])}
end
在Rails 4中,您可以使用where.not
并进一步简化它:
派对模特:
class Party < ActiveRecord::Base
has_many :invitations
scope :invitations_answered, -> { joins(:invitations).merge(Invitation.answered) }
scope :unattended, -> { where.not(id: invitations_answered.pluck(:id)) }
end
邀请模特:
class Invitation < ActiveRecord::Base
belongs_to :party
scope :answered, -> { where.not(status: 'unanswered') }
end