2013-05-01 62 views
3

我想在我的Rails 3项目中使用强大的参数,在单个模型中有大约40-50个模型。Rails 3&强大的参数,获得质量分配错误

我已经完成了以下工作,但是当我尝试创建或更新此模型的一个实例时,我得到了关于质量分配的相同错误,如下所示,它显示模型的每个字段。

我试着从模型中删除accepted_nested_attributes_for并重新启动网络服务器,但它对我收到的错误没有影响。

配置/ application.rb中

config.active_record.whitelist_attributes = false 

应用/模型/ my_service.rb(级联为了简洁)

class CallService < ActiveRecord::Base 

    include ActiveModel::ForbiddenAttributesProtection 

    belongs_to :account 
    has_many :my_service_chargeables 
    accepts_nested_attributes_for :my_forward_schedules, allow_destroy: true 


    validates :start_date, :username, :account_id, :plan_id, presence: true 
    audited associated_with: :account 

    scope :enabled, where(enabled: true) 
    scope :within, lambda{|month| where(start_date: (month.beginning_of_month..month.end_of_month))} 

end 

应用程序/控制器/ my_services_controller.rb

def update 
    @my_service = MyService.find(params[:id]) 
    if @my_service.update_attributes(permitted_params.my_service) 
    flash[:success] = "Service Updated" 
    redirect_to @my_service 
    else 
    render 'edit' 
    end 
end 

应用程序/控制器/ application_controller.rb

def permitted_params 
    @permitted_params ||= PermittedParams.new(current_user, params) 
end 

应用程序/模型/ permitted_pa​​rams.rb

class PermittedParams < Struct.new(:user, :params) 
    def my_service 
    if user && user.role?(:customer) 
     params.require(:my_service).permit(*service_customer_attributes) 
    else 
     params.require(:my_service).permit! 
    end 
    end 

    def service_customer_attributes 
    [:timeout, :pin, :day] 
    end 
end 

ERROR当更新

ActiveModel::MassAssignmentSecurity::Error in MyServicesController#update 

Can't mass-assign protected attributes: account_id, plan_id, start_date, username 

我已经运行一个调试器确认代码从PermittedParams类中碰到params.require(:my_service).permit!行,但这个异常仍然不断抛出,但据我所知,应该没有任何东西导致此模型要求声明属性作为attr_accessible's。

任何人都可以阐明这种行为?

我使用的gem版本(从我Gemfile.lock的):

strong_parameters (0.2.0) 
rails (3.2.11) 
+0

只是出于兴趣,你没有想过在你的模型中添加attr_accessible:account_id,:plan_id,:start_date,:username。正如我知道你知道这个错误“不能大规模分配受保护的属性”通常意味着什么。通过使用'attr_accessible',它将获取一个可访问的属性列表。所有其他属性将受到保护。也可能想在此阅读 - http://guides.rubyonrails.org/security。html#mass-assignment – David 2013-05-02 00:17:03

+2

这会破坏使用强参数gem的目的,因为它意味着处理用户可以通过控制器设置哪些属性的保护。 – bdx 2013-05-02 07:49:16

回答

2

我不知道您的具体使用情况是什么,但这样做params.require(:my_service).permit!似乎仍像一个坏主意在这里,至少有人可能会覆盖你的模型的PK。而不是params.require(:my_service).permit!为什么不这样做:

params.require(:my_service).permit(:timeout, :pin, :day, :account_id, 
    :plan_id, :start_date, :username) 

或者保留这些在另一个数组,并与现有的service_customer_attributes保持其干燥合并。

这会照顾你的质量分配错误,并且会更安全和更明确。