简体   繁体   English

Rails Cancancan 定义了 3 个关联的能力

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM