Rails 4强参数从嵌套模型获得许可

时间:2014-05-21 07:17:20

标签: ruby-on-rails ruby ruby-on-rails-4 strong-parameters

对于强大的参数有几个问题,但我无法找到实现目标的任何答案。请原谅任何重复(也许指向正确的方向)。 我在一个有几个&has -one'的模型中使用强params。关联和嵌套属性与' accepts_attributes_for'。

在我的路线中,我有:( 为了更好的理解而更新

  resources :organisations do
    resources :contact_details
  end

所以,即对于一个相关的模型,我必须使用

def organisation_params
  params.require(:organisation).permit(:org_reference, :supplier_reference, :org_type, :name, :org_members, :business, :contact_person, contact_detail_attributes: [:id, :contactable_id, :contactable_type, :phone, :fax, :mail, :state, :province, :zip_code, :street, :po_box, :salutation, :title, :last_name, :first_name, :description])
end

这有效,但我必须为每个相关模型重新键入所有允许的参数。当我修改 contact_details 的允许属性时,我必须在几个位置(每个具有多态关联的模型)中更改它。

有没有办法获取 contact_details 的参数白名单并将其包含在父白名单中?

类似的东西:

def organisation_params
  my_params = [:org_reference, :supplier_reference, :org_type, :name, :org_members, :business, :contact_person]
  contact_params = #get permitted params, that are defined in contact_details_controller
  params.require(:organisation).permit(my_params, contact_params)
end

我不想解决安全问题,但我已经为contact_details定义了允许的属性,并且不想在每个相关的" parent"中重复它。模型(因为它耗费精力并且很容易出现愚蠢的错误,比如在几个父模型之一中省略一个属性)。

2 个答案:

答案 0 :(得分:1)

使用ApplicationController或共享模块中定义的方法:

  1. ApplicationController

    class ApplicationController
      def contact_details_permitted_attributes
        [:id, :contactable_id, :contactable_type, ...]
      end
    end
    
    class ContactDetailsController < ApplicationController
      def contact_details_params
        params
          .require(contact_details)
          .permit(*contact_details_permitted_attributes)
      end
    end
    
    class OrganisationsController < ApplicationController
      def organisation_params
        params
          .require(:organisation)
          .permit(:org_reference, ..., 
                  contact_detail_attributes: contact_details_permitted_attributes)
      end
    end
    
  2. 共享模块:

    module ContactDetailsPermittedAttributes
      def contact_details_permitted_attributes
        [:id, :contactable_id, :contactable_type, ...]
      end
    end
    
    class ContactDetailsController < ApplicationController
      include ContactDetailsPermittedAttributes
    
      def contact_details_params
        params
          .require(contact_details)
          .permit(*contact_details_permitted_attributes)
      end
    end
    
    class OrganisationsController < ApplicationController
      include ContactDetailsPermittedAttributes
    
      def organisation_params
        params
          .require(:organisation)
          .permit(:org_reference, ..., 
                  contact_detail_attributes: contact_details_permitted_attributes)
      end
    end
    
  3. Rails甚至为concernsapp/controllers内的共享模块app/models提供专用目录;事实上,在您的情况下,您应该使用app/controllers/concerns

答案 1 :(得分:0)

我不明白为什么不。在您的ApplicationController中,您可以拥有

def contact_attributes
  [:id, :contactable_id, :contactable_type, :phone, :fax, 
   :mail, :state, :province, :zip_code, :street, :po_box, 
   :salutation, :title, :last_name, :first_name, :description]
end

然后在你的organisation_params

def organisation_params
  my_params = [:org_reference, :supplier_reference, :org_type, :name, :org_members, :business, :contact_person]

  params.require(:organisation).permit(*my_params, contact_detail_attributes: contact_attributes)
end

在其他地方你可能会......

def contact_params
params.require(:contact).permit(*contact_attributes)
end