“无法修改关联,因为源反射类是通过 :has_many 关联的"; [英] "Cannot modify association because the source reflection class is associated via :has_many"

查看:56
本文介绍了“无法修改关联,因为源反射类是通过 :has_many 关联的";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经查看了具有类似标题和问题的其他问题,但他们的解决方案似乎不适用于我.抱歉没有提供更多描述,我已经达到了 150 个限制.

I've looked at other questions with a similar title and issue, but their solutions do not seem to apply to me. Sorry for not being more descriptive, I was already reaching the 150 limit.

我有以下模型:

class Event < ActiveRecord::Base
  has_many :weeks, dependent: :destroy
  has_many :tests, through: :weeks

  accepts_nested_attribues_for :weeks, allow_destroy: true
  accepts_nested_attribues_for :tests, allow_destroy: true
end

class Week < ActiveRecord::Base
  belongs_to :event
  has_many :tests, dependent: :destroy
end

class Test < ActiveRecord::Base
  belongs_to :week
end

还有这个观点:

=form_for @event do |e|
  %h3 Event
  =render 'form', e: e # This partial contains the general data of the Event.

  %h3 Weeks

  %table
    %thead
      %th Start
      %th End
      %th X
    %tbody
      =e.fields_for :weeks do |w|
        =render 'week_fields', w: w
  =link_to_add_fields 'Add Week', e, :weeks # Custom helper that adds the fields of the week to the end of the table via JavaScript.

  %h3 Tests

  -@weeks.each do |week|
    %h5=week.start # Prints the 'start' of the Week.
    %table
      %thead
        %th Start
        %th End
        %th X
      %tbody
        = e.fields_for :tests, week.tests do |t|
          =render 'test_fields', t: t, s: week.id
    =link_to_add_fields 'Add Test', e, :tests, parent: week.id

这适用于添加事件和周,但是当我尝试添加新测试时,我收到一条错误消息:

This works fine for adding Events and Weeks, but when I try to add a new Test I get an error that says:

无法修改关联Event#tests",因为源反射类Test"通过 :has_many 关联到Week".

我知道这是由于我在视图中获取关联的方式,但我不太确定应该如何使用它们.

I understand this is due to the way I got the associations in the view, but I'm not too sure how I should use them.

这是我上面使用的 link_to_add_fields 助手的代码:

This is the code from the link_to_add_fields helper I'm using above:

def link_to_add_fields(name, f, association, parent: 0)
  new_object = f.object.send(association).klass.new
  id = new_object.object_id
  fields = f.fields_for(association, new_object, child_index: id) do |builder|
    render(association.to_s.singularize + "_fields", f: builder, s: parent)
  end
  link_to(name, '#', class: 'btn btn-default add_fields', id: "add_#{association}", data: {id: id, association: association, fields: fields.gsub("\n", "")})
end

帮助程序生成稍后通过 JavaScript 引入表单的代码.这是 Railcasts 剧集中使用的版本的修改版本.

The helper generates code that's later introduced onto the form via JavaScript. It's a modified version of the one used on a Railcasts episode.

这是我在控制器上用来限制参数的:

This is what I'm using on my controller to limit the parameters:

def event_params
  params.require(:event).permit(:name, :start, :end, :place,
                                 tests_attributes: [:id, :name, :date, :time, :week_id],
                                 weeks_attributes: [:id, :start, :end, :_destroy])
end

这非常适合编辑现有测试的数据,但不适用于助手生成的新数据.我正在阅读(在我的情况下)tests_attributes 应该在 week_attributes 内,因为我试图将 belongs 修改为 Week.像这样:

This works perfectly for editing the data of an already existing Test, but not for new ones generated by the helper. I was reading that (in my case) tests_attributes should be within week_attributes, since the Test I'm trying to modify belongs to Week. like this:

def event_params
  params.require(:event).permit(:name, :start, :end, :place,
     weeks_attributes: [:id, :start, :end, :_destroy, test_attributes: [:id, :name, :date, :time, :week_id]])
end

我不知道如何使表单遵循此关联(或者这是否确实是一个解决方案).我知道 Test 无法修改,因为它被拉为只读,但我不确定如何在视图中安排关联,以便在我更新 Event 时可以保存它.

I do not know how to make the form to follow this association (or if this is actually a solution). I know that Test cannot be modified cause it's being pulled as read-only, but I'm not sure how to arrange the association within the view, so that it can be saved when I update Event.

非常感谢任何指针.

推荐答案

这有点棘手,但我明白了.这是一个修改内容的问题.

This got a bit tricky, but I got it. It was a matter of modifying what was within what.

我通过使用这样的东西让它工作:

I got it working by using something like this:

%h3 Tests

-@weeks.each do |week|
  =e.fields_for :weeks, week do |w|
    %h5=week.start # Prints the 'start' of the Week.
    %table
      %thead
        %th Start
        %th End
        %th X
      %tbody
        = w.fields_for :tests, week.tests do |t|
          =render 'test_fields', t: t, s: week.id
    =link_to_add_fields 'Add Test', w, :tests, parent: week.id

诀窍是使为 Test 生成的字段位于为 Week 生成的字段内.所以首先我添加了 e.fields_for :weeks, week do |w| 表示以下字段属于到 Weeks,然后我将数据限制为当前选定的 Week通过使用前面的 each 循环.

The trick was to make the fields generated for Test to be within the fields generated for Week. So first I added e.fields_for :weeks, week do |w| which would indicate that the following fields belong to Weeks, then I limited the data to the current selected Week by using the previous each loop.

接下来,我在 fields_for 中使用了新的 w 关联进行测试.这将使渲染生成的每个字段都采用event[weeks_attributes][week_id][tests_attributes][test_id]"的格式,这正是我所期待的用于我的控制器中的参数.

Next I used the new w association in the fields_for for Test. This would make every field generated by the render to be in the format of "event[weeks_attributes][week_id][tests_attributes][test_id]" which is what I was expecting for the parameters in my controller.

同样在 link_to_add_fields 中完成,我更改了属于 Event 的 e 关联,用于属于 Weeks 的 w.这也会使用我之前描述的格式更改通过 JavaScript 生成的新记录的格式.

The same is done in link_to_add_fields where I change the e association that belonged to Event, for w which belongs to Weeks. This would also change the format of the new records generated via JavaScript, using the format I previously described.

最后,我不得不更改控制器中预期的格式.我使用的是单数形式 test,它必须改为复数形式,因为可以在表单中添加多条记录.所以我最终得到了这样的结果:

Finally, I had to change the format expected in the controller. I was using the singular form test, it had to be changed to plural, as it is possible to add multiple records in the form. So I ended up with something like this:

def event_params
  params.require(:event).permit(:name, :start, :end, :place,
     weeks_attributes: [:id, :start, :end, :_destroy, tests_attributes: [:id, :name, :date, :time, :week_id]])
end

它有效!

这篇关于“无法修改关联,因为源反射类是通过 :has_many 关联的";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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