概述
我正在尝试从父控制器授权子对象并强制执行子资源的功能。我正在使用nested_forms
gem创建表单以及gem的link_to_add
和link_to_delete
功能来正确处理子资源(https://github.com/ryanb/nested_form#usage)。
守则
-activity_controller.rb
class ActivityController < ApplicationController
load_and_authorize_resource
load_and_authorize_resource :component, through: :activity
def new
@activity = Activity.new
end
def create
@activity = Activity.new(activity_params)
if @activity.save
return redirect_to action: :show, id: @activity.id
else
render action: :new
end
end
def show
end
def activity_params
params.require(:activity).permit(components_attributes: [:id, :start_date, :end_date, :_destroy, :mon_hrs, :tue_hrs, :wed_hrs, :thu_hrs, :fri_hrs, :sat_hrs, :sun_hrs, :full_time])
end
end
-activity.rb
class Activity < ActiveRecord::Base
has_many :components
accepts_nested_attributes_for :components, allow_destroy: true
end
-component.rb
class Component < ActiveRecord::Base
belongs_to :activity
end
-ability.rb
class Ability
include CanCan::Ability
def initialize(user)
if user.has_role? 'student'
can [:read, :create, :update], Activity, person_id: user.id
can [:read, :create, :update], Component, :activity => { person_id: user.id }
end
end
end
-activity / new.html.erb
<%= nested_form_for @activity do |f| %>
<div class="row">
<div class="span12 text-right">
<%= f.link_to_add "Add Time Period", :components,
data: { target: "#time-period" },
class: 'btn btn-prmary add-time-period' %>
</div>
</div>
<%= f.fields_for :components %>
<!-- fields for components are here -->
<div class="row">
<div class="span4">
<%= f.link_to_remove "Delete Time Period", class: 'pull-right btn btn-prmary'%>
</div>
</div>
<%= end %>
我从上面遗漏了很多代码,但这些代码片段是相关的。无论如何,问题是表单允许我创建组件并在我不应该删除它们。由于我没有赋予destroy
组件资源的能力,因此不应该允许我删除。
我怀疑nested_forms
gem正在通过使用_destroy
标志并绕过CanCanCan的授权来销毁子对象(组件)。
有没有人知道在从父资源创建/删除/更新子对象时强制执行在子对象上设置的功能的方法?
我希望这一切都有意义!
谢谢!