Rails REST API-基于模型的嵌套关联为无格式编码属性的json输入生成允许的字段

时间:2018-11-06 13:34:00

标签: json ruby rest ruby-on-rails-5

我正在为应用程序的工厂生成器开发REST Api,以允许也使用REST创建模型实例,我想知道如何允许模型的嵌套属性而无需对属性进行硬编码。

假设我有一个名为“餐厅”的模型

class Restaurant < ApplicationRecord
  has_one :cost, dependent: :destroy, inverse_of: :grant
  has_one :address, dependent: :destroy, inverse_of: :grant
  has_one :owner, dependent: :destroy, inverse_of: :grant

  accepts_nested_attributes_for :cost, :address, :owner
  ...

其中的关联也具有其自己的模型属性和一个工厂

FactoryGirl.define do factory :restaurant, class Restaurant do

  after(:create) do |restaurant|
    restaurant.cost = assign_attributes(attributse_for(:cost_factory))
    restuarnat.address = assign_attributes(attributes_for(:address_factory))
    restaurant.owner = assign_attributes(attributes_for(:owner_factory))
  end
 ...
end

,其中的嵌套关​​联也有自己的工厂。我正在以这种格式通过REST API传递JSON正文

{
  "restaurant": {
    "cost_attributes": {
     "staff": 123
     "tables": 123
    }
}

我知道我可以通过这些方式允许属性

params.permit(:restaurant)
      .permit(cost_attributes: [:staff, :tables],
              address_attributes: [:address_attr_1],
              owner_attributes: [:owner_attr_1]]

但是我正在使用的实际模型有很多关联。对所有内容进行硬编码将很痛苦。 有没有办法我可以允许参数通过而不是在控制器中进行硬编码?目前,这就是我的想法

params.permit(Restaurant.nested_attributes_options.keys)

但是显然这行不通。

2 个答案:

答案 0 :(得分:1)

这是收集嵌套属性名称的一种方法:

mod = Restaurant

nested_attributes = mod.nested_attributes_options.keys.each_with_object({}) do |association, hash|
  hash[:"#{association}_attributes"] = association.
                                       to_s.
                                       classify.
                                       constantize.
                                       send(:attribute_names).
                                       map(&:to_sym)
end
params.permit(:restaurant).permit(nested_attributes)

此代码有点通用,请随时根据您的特定用例进行修改。

答案 1 :(得分:0)

要改善您的答案,以下是一种使用反射递归收集所有深层嵌套属性名称的方法:

IF'S