[英]Rails Cancancan define ability on 3 association
Using Rails 6 and CanCanCan.使用 Rails 6 和 CanCanCan。 Here are my models:这是我的模型:
class Shop < ApplicationRecord
has_many :shop_reviews, dependent: :destroy
end
class ShopReview < ApplicationRecord
belongs_to :shop, counter_cache: true
belongs_to :user_profile, counter_cache: true
end
class User < ApplicationRecord
has_one :user_profile, dependent: :destroy
has_many :shop_reviews, through: :user_profile
end
class UserProfile < ApplicationRecord
belongs_to :user
has_many :shop_reviews
end
ShopReview table: ShopReview表:
id, shop_id, user_profile_id, review
Association: 1. A shop can have many reviews 2. Only one User Profile can have one review on a shop关联: 1. 一个店铺可以有很多评论 2. 一个店铺只能有一个 User Profile 有一个评论
Abilities I want to define: 1. User Profile can edit, update, destroy his own review of a shop 2. User Profile cannot create a new review if a review of his exist on that shop我想定义的能力: 1. 用户个人资料可以编辑、更新、销毁他自己对商店的评论 2. 如果该商店存在他的评论,则用户个人资料不能创建新评论
What I tried:我试过的:
class Ability
include CanCan::Ability
def initialize(user)
can :read, :all
if user.present?
can [:update, :destroy], ShopReview, user_profile_id: user.user_profile.id
can :create, ShopReview do
!ShopReview.exists?(user_profile_id: user.user_profile.id, shop_id: :shop_id)
end
end
end
end
But I can't seem to pass in the shop_id
on visiting /shops/11/shop_reviews/new.但是我似乎shop_id
在访问 /shops/11/shop_reviews/new 时传递 shop_id。 Here's the log:这是日志:
Started GET "/shops/11/shop_reviews/new" for 127.0.0.1 at 2020-01-04 00:23:10 +0800
Processing by ShopReviewsController#new as HTML
Parameters: {"shop_id"=>"11"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 9], ["LIMIT", 1]]
UserProfile Load (0.2ms) SELECT "user_profiles".* FROM "user_profiles" WHERE "user_profiles"."user_id" = $1 LIMIT $2 [["user_id", 9], ["LIMIT", 1]]
↳ app/models/ability.rb:9:in `initialize'
ShopReview Exists? (0.3ms) SELECT 1 AS one FROM "shop_reviews" WHERE "shop_reviews"."user_profile_id" = $1 AND "shop_reviews"."shop_id" = $2 LIMIT $3 [["user_profile_id", 8], ["shop_id", nil], ["LIMIT", 1]]
↳ app/models/ability.rb:11:in `block in initialize'
Shop Load (0.2ms) SELECT "shops".* FROM "shops" WHERE "shops"."id" = $1 ORDER BY "shops"."created_at" DESC LIMIT $2 [["id", 11], ["LIMIT", 1]]
You should use gem pundit
to create authorizations in your app.您应该使用 gem pundit
在您的应用程序中创建授权。 Pundit is easy to scale than gem cancancan
. Pundit 比 gem cancancan
更容易扩展。 Because pundit
allows your app to create authorization on each model.因为pundit
允许您的应用在每个模型上创建授权。 You can search more about two gems and choose what is most suitable for you.您可以搜索更多关于两颗宝石的信息并选择最适合您的宝石。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.