的has_many協會有許多不同的方法可用,包括find
current_user.model.find(params[:id])
這類似於
Model.where(user_id: current_user.id).find(params[:id])
如果你必須要經過幾個模型,以達到您的用戶模型,例如
class User < ApplicationRecord
has_one :test_one
end
class TestOne < ApplicationRecord
has_one :test_three
belongs_to :user
end
class TestThree < ApplicationRecord
has_many :test_fours
belongs_to :test_one
end
class TestFour < ApplicationRecord
belongs_to :test_three
end
您可以通過做一些像
TestFour.joins(:test_three => { :test_one => :user }).where(test_threes: { test_ones: { users: { id: current_user.id}}}).find(1)
# TestFour Load (1.2ms) SELECT "test_fours".* FROM "test_fours" INNER JOIN "test_threes" ON "test_threes"."id" = "test_fours"."test_three_id" INNER JOIN "test_ones" ON "test_ones"."id" = "test_threes"."test_one_id" INNER JOIN "users" ON "users"."id" = "test_ones"."user_id" WHERE "users"."id" = $1 AND "test_fours"."id" = $2 LIMIT $3 [["id", 1], ["id", 1], ["LIMIT", 1]]
#=> #<TestFour id: 1, test_three_id: 1, created_at: "2017-07-12 21:06:51", updated_at: "2017-07-12 21:06:51">
設置它在一個單一的查詢,然後,如果你這樣做有一個用戶ID /蟲蟲的ID不匹配:
TestFour.joins(:test_three => { :test_one => :user }).where(test_threes: { test_ones: { users: { id: current_user.id + 1}}}).find(1)
# TestFour Load (0.8ms) SELECT "test_fours".* FROM "test_fours" INNER JOIN "test_threes" ON "test_threes"."id" = "test_fours"."test_three_id" INNER JOIN "test_ones" ON "test_ones"."id" = "test_threes"."test_one_id" INNER JOIN "users" ON "users"."id" = "test_ones"."user_id" WHERE "users"."id" = $1 AND "test_fours"."id" = $2 LIMIT $3 [["id", 2], ["id", 1], ["LIMIT", 1]]
#=> ActiveRecord::RecordNotFound: Couldn't find TestFour with 'id'=1 [WHERE "users"."id" = $1]
這是怎麼回事工作表現明智嗎?從current_user我必須通過3有時4種不同的關係,才能達到我想要的模型。有很大的懲罰嗎? – Rudi
@Rudi如果你通過關聯做了它,它會引發幾個SQL查詢。我已經更新了我的答案,以一個經歷了幾個模型('TestOne'和'TestThree')的例子來加載'TestFour'模型,只有當'user_id'匹配當前用戶 –
另外,正如Jason Brodie提到的一樣'CanCan'對於限制訪問和[甚至看起來像](https://github.com/CanCanCommunity/cancancan/wiki/defining-abilities#hash-of-conditions)是非常好的,你可以通過關聯(就像在我的最後一個例子)也設置了限制,儘管我從來沒有做過任何複雜的事情,所以不確定你如何設置一個等效的例子以及它的效果。 –