讓我們嘗試重組你的問題一點,與has_many, through
協會替換has_and_belongs_to_many
協會,我們將增加對Character
模型的另一個has_many, through
協會如下:
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, through: :memberships
has_many :characters
end
class Character < ActiveRecord::Base
belongs_to :user
has_many :groups, through: :user
end
的Membership
模型是關係的表示在User
和Group
之間 - 實質上是使用has_and_belongs_to_many
時隱藏的連接表。我更喜歡看到這種關係(特別是如果它很重要)。
我們還有一個Character
型號到Group
與用戶關聯。當我們嘗試加入我們的示波器時,這很有幫助。
充實的Character
模型出來,讓我們添加以下內容:
sifter :by_user do |user|
user_id == user.id
end
sifter :public do
public
end
使用篩作爲我們的基石,我們可以添加以下獲得可見字符(如你定義它):
def self.get_visible(user)
Character.uniq.joins{groups.outer}.where{(sift :public)|(sift :by_user, user)|(groups.id.in(user.groups))}
end
此方法採用的User
一個實例,並發現以下Character
S:
- 所有公共字符。
- 所有用戶的角色。
- 屬於用戶組的所有字符。
然後我們只從這些集合中取出不同的字符列表。
從鐵軌控制檯:
irb(main):053:0> Character.get_visible(User.find(4))
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 4]]
Group Load (0.7ms) SELECT "groups".* FROM "groups" INNER JOIN "memberships" ON "groups"."id" = "memberships"."group_id" WHERE "memberships"."user_id" = 4
Character Load (0.9ms) SELECT DISTINCT "characters".* FROM "characters" LEFT OUTER JOIN "users" ON "users"."id" = "characters"."user_id" LEFT OUTER JOIN "memberships" ON "memberships"."user_id" = "users"."id" LEFT OUTER JOIN "groups" ON "groups"."id" = "memberships"."group_id" WHERE ((("characters"."public" OR "characters"."user_id" = 4) OR "groups"."id" IN (2)))
[
[0] #<Character:0x00000005a16b48> {
:id => 4,
:user_id => 4,
:name => "Testiculies",
:created_at => Tue, 13 Aug 2013 14:35:50 UTC +00:00,
:updated_at => Tue, 13 Aug 2013 14:35:50 UTC +00:00,
:public => nil
},
[1] #<Character:0x00000005d9db40> {
:id => 1,
:user_id => 1,
:name => "conan",
:created_at => Mon, 12 Aug 2013 20:18:52 UTC +00:00,
:updated_at => Tue, 13 Aug 2013 12:53:42 UTC +00:00,
:public => true
}
]
要查找所有字符的特殊User
有,添加一個實例方法的User
型號:
def get_visible_characters
Character.get_visible(self)
end
我覺得要,將讓你走。
天哪,得到了這個風滾草:沒有人知道,沒有人在乎... – McLibboc 2013-04-18 15:05:12