所以这里涉及很多关系。最终目标是在活动视图上显示来自current_user的联系人列表中参加活动的人。当前的模型布局如下:
# Table name: profiles
# id :integer not null, primary key
# profileable_id :integer
# profileable_type :string(255)
class Profile < ActiveRecord::Base
belongs_to :profileable, polymorphic: true
has_many :events, as: :eventable, dependent: :destroy
end
# Table name: events
# id :integer not null, primary key
# eventable_id :integer
# eventable_type :string(255)
class Event < ActiveRecord::Base
belongs_to :eventable, polymorphic: true
has_many :attendants, dependent: :destroy
end
# Table name: attendants
# id :integer not null, primary key
# referrer_profile_id :integer
# event_id :integer
# responding_profile_id :integer
class Attendant < ActiveRecord::Base
belongs_to :event
end
# Table name: contacts
# id :integer not null, primary key
# user_id :integer
class Contact < ActiveRecord::Base
belongs_to :user
has_one :profile, as: :profileable, dependent: :destroy
end
显然,一些更多关系相关的行会有所帮助,一些范围和一些东西可以帮助加入(我相信)。
我希望做的事情就像:
@attendants = Attendant.where(event_id: @event.id)
@contacts = Contacts.where(user_id: current_user.id)
@result = @attendents.select {|i| @contacts.any? {|c| i.responding_profile_id == c.profile.id } }
据我所知,这是效率最低的方法。如果您可以帮助我使用正确的加入,合并,范围以及其他拥有/属于关系行完成这一点我将永远感激不尽!
这是关系模型图。配置文件和事件是多态的。服务员是一个关系表。
我查询了Attendant和Profile为JSON的示例。也许这会有所帮助。
Contact.find(8).profile.as_json
Contact Load (0.6ms) SELECT "contacts".* FROM "contacts" WHERE "contacts"."id" = $1 LIMIT 1 [["id", 8]]
Profile Load (0.3ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."profileable_id" = $1 AND "profiles"."profileable_type" = $2 LIMIT 1 [["profileable_id", 8], ["profileable_type", "Contact"]]
=> {"id"=>11, "first_name"=>"Apple", "last_name"=>"Dumpling", "profileable_id"=>8, "profileable_type"=>"Contact", "created_at"=>Fri, 10 Oct 2014 02:21:20 UTC +00:00, "updated_at"=>Fri, 10 Oct 2014 02:21:20 UTC +00:00}
Attendant.second.as_json
Attendant Load (0.8ms) SELECT "attendants".* FROM "attendants" ORDER BY "attendants"."id" ASC LIMIT 1 OFFSET 1
=> {"id"=>2, "confirmation"=>"attending", "referrer_profile_id"=>1, "responding_profile_id"=>8, "event_id"=>1, "created_at"=>Fri, 10 Oct 2014 17:46:44 UTC +00:00, "updated_at"=>Fri, 10 Oct 2014 17:46:44 UTC +00:00}
答案 0 :(得分:1)
我无法在没有您的数据库的情况下对其进行测试,但是查看您的架构,这应该返回当前用户参与给定事件的每个联系人的个人资料。
Profile.where('id
IN (SELECT attendants.responding_profile_id FROM attendants WHERE attendants.responding_profile_id
IN (SELECT profiles.id FROM profiles WHERE profiles.id
IN(SELECT contacts.profile_id FROM contacts WHERE contacts.user_id = ?))
AND attendants.event_id = ?)', current_user.id, @event.id)
答案 1 :(得分:1)
我不确定这是否正确但是我在这里看到了你的架构:
Profile.select(Arel.star).where(
Profile.arel_table[:profileable_id].in(
Event.select(Attendant.arel_table[:responding_profile_id]).where(
Event.arel_table[:id].eq(@event.id).and(
Attendant.arel_table[:responding_profile_id].in(
Attendant.select(Attendant.arel_table[:responding_profile_id]).where(
Contact.arel_table[:user_id].eq(current_user_id)
).joins(
Attendant.arel_table.join(Contact.arel_table).on(
Attendant.arel_table[:responding_profile_id].eq(Contact.arel_table[:id])
).join_sources
).ast
)
)
).ast
)
)
这是用于参考的SQL:
SELECT * from Profile
where Profile.profileable_id in
(select Attendant.responding_profile_id from Event
where Event.id = @event.id
and Attendant.responding_profile_id in
(select Attendant.responding_profile_id from Attendant inner join Contact
on Attendant.responding_profile_id = Contact.id
where Contact.user_id = current_user_id
)
)
答案 2 :(得分:0)
这个问题是多态的配置文件意味着它通过它的关联表选择它的父母。在我的问题中,我曾要求使用相同的ID /类型为两个不同的父项找到相同的配置文件。这是不可能的,因为它不一样。 当前代码不起作用。为了解决这个问题,我在 original_profile_id 的Contact
添加了一个字段,该字段在人员的个人资料重复时被写入,以便始终拥有对原始资源的引用。现在突然间,因为不可能,所以很难复杂,很容易得到补救。