In my app I have Permission table, which stores all the logic what User can do. With Pundit I want to allow User to create new Campaign if Permission table allows. User can access Campaigns and create new, if Permission table contains this info:
- permitable_type: Sysmodule // another table where I store info on System sections, where Campaigns is one of
- permitable_id: 2 // means Campaigns from Sysmodule
- level: 3 // means User can edit something in Campaigns section
So far I keep getting error "Pundit::NotDefinedError", unable to find policy of nil policies/application_policy.rb is standart, no changes. Obviously I am doing sothing wrong. How do I do this authorization correctly? Many thanks for any help! I am on Rails 5 + Pundit.
models/permission.rb
class Permission < ApplicationRecord
belongs_to :permitable, polymorphic: true
belongs_to :user
enum level: {owner: 1, view: 2, edit: 3}
end
models/user.rb
has_many :permissions
has_many :campaigns, through: :permissions, source: :permitable, source_type: 'Campaign' do
def owner_of
where('`permissions`.`level` & ? > 0', Permission::owner )
end
end
has_many :sysmodules, through: :permissions, source: :permitable, source_type: 'Sysmodule' do
def can_access
where('`permissions`.`level` & ? > 1', Permission::can_access )
end
end
controllers/campaigns_controller.rb
def new
@campaign = Campaign.new
authorize @campaign
end
policies/campaign_policy.rb
class CampaignPolicy < ApplicationPolicy
attr_reader :user, :campaign, :permission
@user = user
@permission = permission
end
def new?
user.permission? ({level: 3, permitable_type: "Sysmodule", permitable_id: 2})
end
views/campaigns/index.html.erb
<% if policy(@campaign).new? %>
</li>
<li><%= link_to "New campaign", new_campaign_path(@campaign) %></li>
</li>
<% end %>