更新深度嵌套模式与轨和angularjs [英] Updating deeply nested models with rails and angularjs

查看:139
本文介绍了更新深度嵌套模式与轨和angularjs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经研究了这个问题非常多,专门为深嵌套模型无解。我想出了以下修补程序,不知道是否有更好的方法。

I have researched this question very much, with no solution specifically for deeply nested models. I have come up with the following fix, wondering if there is a better way.

我试图削减下来是几乎一样简单,我可以把它解释这个问题,我的解决方案。

I've tried to cut this down to be nearly as simple as I can make it to explain the issue and my solution.

问题是,存在着以下的ActiveRecord模型轨道:

The issue is that there exist the following ActiveRecord models in rails:

class Template
has_many :sections, dependent: :destroy
accepts_nested_attributes_for :sections
has_many :columns, through: :sections, dependent: :destroy
has_many :fields, through: :columns, dependent: :destroy

class Section
belongs_to :template
has_many :columns, dependent: :destroy
accepts_nested_attributes_for :columns

class Column
belongs_to :section
has_many :fields, dependent: :destroy
accepts_nested_attributes_for :fields

class Field
belongs_to :column‏

和角度,我们的目标是一个单一的ngResource $资源呼叫发送到'模板/:身份证'和更新整个儿链。 (每片链之前创建的,在模板创建过程。当模板定稿时需要有一个统一的更新。)

and in angular, the goal is to send a single ngResource $resource call to 'templates/:id' and update the entire chain of children. (Each piece of the chain is created prior, in the template creation process. The need for a unified update occurs when the template is finalized.)

### ClassFactory.coffee ###
#
# Create a connection to the API
# ...
    return $resource('api/:class/:id', { format: 'json' }, {...})
# ...

### EditTemplateController.coffee ###
#
# Create angular template resource, save it, and redirect to editing view
# ...
    $scope.template = new ClassFactory({class: 'templates'})
    $scope.template.$save({class: 'templates'}, (res)->
        $location.path('templates/'+res.id+'/edit')
    )
#
# Update the angular object
# ...
    $scope.saveTemplate = ->
        $scope.template.$update({class: 'templates', id: $scope.template.id})
#...

### templates_controller.rb ###
#
# Create a single DB interaction with deliberately declared parameters and nested *_attributes parameters
# ...
  def update
    params[:template][:sections_attributes] = params[:sections]
    params[:template][:sections_attributes].each do |paramSection|
      paramSection[:columns_attributes] = paramSection[:columns]
      paramSection[:columns_attributes].each do |paramColumn|
        paramColumn[:fields_attributes] = paramColumn[:fields]
      end
    end
    template = current_user.templates.find(params[:id])
    template.update_attributes(allowed_params)
    head :no_content
  end

  private
    def allowed_params
      params.require(:template).permit(
        :name, sections_attributes: [
          :id, :name, columns_attributes: [
            :id, :fields_attributes: [
              :id, :name, :value
            ]
          ]
        ]
    end
# ...

据我已经制定出来,修复是声明* _attributes如上图所示:

As far as I have worked out, the fix is to declare *_attributes as shown above:

params[:template][:sections_attributes] = params[:sections]

由于角无力送参数Rails是寻找格式。

because of angular's inability to send the format of parameters that rails is looking for.

这显然感觉就像一个哈克的解决方案。有没有更好的办法,而使用angularjs处理深度嵌套的轨道模式?

This obviously feels like a hacky solution. Is there no better way to handle deeply nested rails models while using angularjs?

推荐答案

此GitHub上的Rails问题,这是与AngularJS $资源发送参数使用 accepts_nested_attributes_for

As discussed in this Rails github issue, this is an acknowledged issue with the way that AngularJS $resource sends parameters, versus what Rails expects when using accepts_nested_attributes_for.

每这一问题,并且直到在Rails解决这个解决了,这里是可以在上述实施例可以改变以分离其各部分更可管理的一个位

Per that issue, and until this is resolved in a Rails fix, here is what can be changed in the above example to separate its parts to be a bit more manageable:

添加到任何轨道控制器,模型使用 accepts_nested_attributes_for

Add to any rails controller which model uses accepts_nested_attributes_for:

class ModelController < ApplicationController
  nested_attributes_names = Model.nested_attributes_options.keys.map do |key| 
    key.to_s.concat('_attributes').to_sym
  end

  wrap_parameters include: Model.attribute_names + nested_attributes_names

  # ...
end

移动清理滑轨控制器Update方法嵌套的 * _属性声明的AngularJS控制器保存模型前:

Clean up the Rails controller Update method by moving the nested *_attributes declarations to the AngularJS controller before saving the model:

$scope.saveTemplate = ->
    $scope.template.sections_attributes = $scope.template.sections
    $scope.template.sections_attributes.forEach((section)->
        section.columns_attributes = section.columns
        section.columns_attributes.forEach((column)->
            column.fields_attributes = column.fields
        )
    )
    $scope.template.$update({class: 'templates', id: $scope.template.id})

这不是pretty但是这一切似乎可以为这一非常具体的问题进行,直到它打补丁。

It's not pretty but that's seemingly all that can be done for this very specific issue until it's patched.

这篇关于更新深度嵌套模式与轨和angularjs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆