【问题标题】:accepts_nested_attributes_for alias?接受_nested_attributes_for 别名?
【发布时间】:2012-06-18 07:05:09
【问题描述】:

在Topic 模型中:

class Topic < ActiveRecord::Base
  has_many :choices, :dependent => :destroy
  accepts_nested_attributes_for :choices
  attr_accessible :title, :choices
end

在 POST 创建期间,提交的 params 是 :choices,而不是 Rails 预期的 :choices_attributes,并给出错误:

ActiveRecord::AssociationTypeMismatch (Choice(#70365943501680) expected,
got ActiveSupport::HashWithIndifferentAccess(#70365951899600)):

有没有办法配置 accepts_nested_attributes_for 以接受在 JSON 调用中作为 choices 而不是 choices_attributes 传递的参数?

目前,我在控制器中创建了属性(这似乎不是一个优雅的解决方案):

  def create
    choices = params[:topic].delete(:choices)
    @topic = Topic.new(params[:topic])
    if choices
      choices.each do |choice|
        @topic.choices.build(choice)
      end
    end
    if @topic.save
      render json: @topic, status: :created, location: @topic
    else
      render json: @topic.errors, status: :unprocessable_entity
    end
  end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 json


    【解决方案1】:

    这是一个较老的问题,但我遇到了同样的问题。有没有其他方法可以解决这个问题?看起来“_attributes”字符串是在nested_attributes.rb 代码中硬编码的(https://github.com/rails/rails/blob/master/activerecord/lib/active_record/nested_attributes.rb#L337)。

    在提交表单时将“choices_attributes”分配给属性很好,但如果它用于 API 会怎样。在那种情况下,它只是没有意义。

    在为 API 传递 JSON 时,有没有人有办法解决这个问题或替代方案?

    谢谢。

    更新:

    好吧,因为我还没有听到任何关于这方面的更新,所以我将展示我现在是如何解决这个问题的。作为 Rails 的新手,我愿意接受建议,但这是我目前唯一能解决的方法。

    我在我的 API base_controller.rb 中创建了一个 adjust_for_nested_attributes 方法

    def adjust_for_nested_attributes(attrs)     
      Array(attrs).each do |param|
        if params[param].present? 
          params["#{param}_attributes"] = params[param]
          params.delete(param)
        end
      end
    end
    

    此方法基本上将传入的任何属性转换为#{attr}_attributes,以便它与accepts_nested_attributes_for一起使用。

    然后在每个需要此功能的控制器中,我添加了一个 before_action 像这样

    before_action only: [:create] do 
      adjust_for_nested_attributes(:choices) 
    end
    

    现在我只担心创建,但如果您需要它进行更新,您可以将其添加到 before_action 的 'only' 子句中。

    【讨论】:

      【解决方案2】:

      您可以在模型中创建方法choices=

      def choices=(params)
        self.choices_attributes = params
      end
      

      但是你会破坏你的选择关联的设置器。

      最好的方法是修改表单以返回choices_attributes 而不是choices

      【讨论】:

        【解决方案3】:
          # Adds support for creating choices associations via `choices=value`
          # This is in addition to `choices_attributes=value` method provided by
          # `accepts_nested_attributes_for :choices`
          def choices=(value)
            value.is_a?(Array) && value.first.is_a?(Hash) ? (self.choices_attributes = value) : super
          end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-04
          • 2011-01-13
          • 1970-01-01
          相关资源
          最近更新 更多