gpt4 book ai didi

ruby-on-rails - Rails - 如何在不使用 Accepts_nested_attributes_for 的情况下管理嵌套属性?

转载 作者:行者123 更新时间:2023-12-04 15:00:37 25 4
gpt4 key购买 nike

我的问题是我遇到了accepts_nested_attributes_for 的限制,所以我需要弄清楚如何自己复制该功能以获得更大的灵 active 。 (请参阅下文,了解究竟是什么让我感到困惑。)所以我的问题是:如果我想模仿和增加accepts_nested_attributes_for,我的表单、 Controller 和模型应该是什么样子?真正的诀窍是我需要能够使用现有的关联/属性更新现有的和新的模型。

我正在构建一个使用嵌套表单的应用程序。我最初使用这个 RailsCast 作为蓝图(利用accepts_nested_attributes_for):Railscast 196: Nested Model Form .

我的应用程序是带有作业(任务)的 list ,我让用户更新 list (名称、描述)并在一个表单中添加/删除关联的作业。这很好用,但是当我将它合并到我的应用程序的另一个方面时遇到了问题:通过版本控制历史。

我的应用程序的很大一部分是我需要为我的模型和关联记录历史信息。我最终推出了自己的版本控制(here 是我的问题,我在其中描述了我的决策过程/考虑因素),其中很大一部分是一个工作流程,我需要创建旧事物的新版本,更新新版本,存档旧版本。这对用户来说是不可见的,他们认为这种体验只是通过 UI 更新模型。

代码 - 模型

#checklist.rb
class Checklist < ActiveRecord::Base
has_many :jobs, :through => :checklists_jobs
accepts_nested_attributes_for :jobs, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end

#job.rb
class Job < ActiveRecord::Base
has_many :checklists, :through => :checklists_jobs
end

代码 - 当前形式(注意:@jobs 被定义为 list Controller 编辑操作中此 list 的未归档作业;@checklist 也是如此)
<%= simple_form_for @checklist, :html => { :class => 'form-inline' } do |f| %>
<fieldset>
<legend><%= controller.action_name.capitalize %> Checklist</legend><br>

<%= f.input :name, :input_html => { :rows => 1 }, :placeholder => 'Name the Checklist...', :class => 'autoresizer' %>
<%= f.input :description, :input_html => { :rows => 3 }, :placeholder => 'Optional description...', :class => 'autoresizer' %>

<legend>Jobs on this Checklist - [Name] [Description]</legend>

<%= f.fields_for :jobs, @jobs, :html => { :class => 'form-inline' } do |j| %>
<%= render "job_fields_disabled", :j => j %>
<% end %>
</br>
<p><%= link_to_add_fields "+", f, :jobs %></p>

<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to 'Cancel', checklists_path, :class => 'btn' %>
</div>
</fieldset>
<% end %>

代码 - 来自 checklists_controller.rb#Update 的片段
def update
@oldChecklist = Checklist.find(params[:id])

# Do some checks to determine if we need to do the new copy/archive stuff
@newChecklist = @oldChecklist.dup
@newChecklist.parent_id = (@oldChecklist.parent_id == 0) ? @oldChecklist.id : @oldChecklist.parent_id
@newChecklist.predecessor_id = @oldChecklist.id
@newChecklist.version = (@oldChecklist.version + 1)
@newChecklist.save

# Now I've got a new checklist that looks like the old one (with some updated versioning info).

# For the jobs associated with the old checklist, do some similar archiving and creating new versions IN THE JOIN TABLE
@oldChecklist.checklists_jobs.archived_state(:false).each do |u|
x = u.dup
x.checklist_id = @newChecklist.id
x.save
u.archive
u.save
end

# Now the new checklist's join table entries look like the old checklist's entries did
# BEFORE the form was submitted; but I want to update the NEW Checklist so it reflects
# the updates made in the form that was submitted.
# Part of the params[:checklist] has is "jobs_attributes", which is handled by
# accepts_nested_attributes_for. The problem is I can't really manipulate that hash very
# well, and I can't do a direct update with those attributes on my NEW model (as I'm
# trying in the next line) due to a built-in limitation.
@newChecklist.update_attributes(params[:checklist])

这就是我遇到 accept_nested_attributes_for 限制的地方(它的记录很好 here 。我得到“找不到 ID=X 的 Model1 和 ID=Y 的 Model2”异常,这基本上是按设计的。

那么,如何创建多个嵌套模型并在父模型的表单上添加/删除它们,类似于 accept_nested_attributes_for 所做的,但我自己?

我见过的选项 - 是最好的选项之一吗? 真正的诀窍是我需要能够使用现有的关联/属性更新现有的和新的模型。 我无法链接它们,所以我将命名它们。

繁文缛节(在 github 上)
Virtus(也是 github)

谢谢你的帮助!

最佳答案

您可能想要删除复杂的 Accepts_nested 内容并创建一个自定义类或模块来包含所需的所有步骤。

这篇文章中有一些有用的东西

http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

特别是第3点

关于ruby-on-rails - Rails - 如何在不使用 Accepts_nested_attributes_for 的情况下管理嵌套属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15648396/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com