【发布时间】:2018-01-04 18:00:04
【问题描述】:
我有一个关于模型更新的一般性问题,我想这与如何以尽可能“Rails-y”的方式组织模型和控制器操作的更大问题有关。对于给定的模型Profile(以及它的关联),我有多个更新表单。例如,一种形式可能用于更新first_name、last_name 等基本信息,另一种可能用于更新age、jobs 等内容。在我的例子中,有 8 种不同的形式,它们比我给出的例子要复杂一些。我想知道处理此设置的不同方式之间的权衡。过去我尝试了 3 种不同的方法:
1) 具有自定义控制器操作(在 Profiles 控制器中)来处理这些不同的更新表单。例如。
#views
<%= simple_form_for @profile, url: profile_update_name_path(@profile), method: :patch, remote: true do |f| %>
# the form fields
<% end %>
<%= simple_form_for @profile, url: profile_update_basics_path(@profile), method: :patch, remote: true do |f| %>
# other form fields
<% end %>
#profiles controller
def update_name
if @profile.update
# do some stuff
end
end
def update_basics
if @profile.update
# do some different stuff
end
end
2) 传入一个额外的参数作为表单 url 的一部分,以区分对表单的响应。例如。
#views
<%= simple_form_for @profile, url: profile_path(update_form: “name-form”), method: :patch, remote: true do |f| %>
# the form fields
<% end %>
<%= simple_form_for @profile, url: profile_path(update_form: “basics-form”), method: :patch, remote: true do |f| %>
# the form fields
<% end %>
#profiles controller
def update
if params[:update_form] == "name-form"
if @profile.update
# do some stuff
else
# handle errors
end
elsif params[:update_form] == "basics-form"
if @profile.update
# do some different stuff
else
# handle different errors
end
end
end
3) 将模型分解为单独的更小的类,这些类都通过 has_one、belongs_to 关系以某种方式连接到父模型 Profile 模型。例如。
#profile.rb
has_one :name_information, dependent: :destroy
has_one :basic_information, dependent: :destroy
has_many :jobs, through: :basic_information
#name_information.rb
# has attributes: first_name, last_name
belongs_to :profile, touch: true
#basic_information.rb
# has attributes: age
belongs_to :profile, touch: true
has_many :jobs, dependent: :destroy
accepts_nested_attributes_for :jobs, allow_destroy: true
#views
# each form now points to the update action for it's own controller rather than using the profiles_controller
<%= simple_form_for [@profile, @name_information], url: profile_name_information_path(@profile, @name_information), method: :patch, remote: true do |f| %>
# the form fields
<% end %>
<%= simple_form_for [@profile, @name_information], url: profile_name_information_path(@profile, @name_information), method: :patch, remote: true do |f| %>
# the form fields
<% end %>
我在使用所有这些技巧方面取得了一些成功,但老实说,我不确定它们中的任何一个都是很好的练习。有人对处理这种设置的最佳“Rails”方式有什么想法吗?将事物分解为更小的类的第三种选择似乎对我来说可能是最好的,但它对于大型应用程序的吸引力也较小,因为更改这些基本模型将对整个应用程序产生重大影响。这也让我想知道加载一堆较小的关联对象的效率,这些对象很容易成为一个类的一部分。
【问题讨论】:
-
我投票结束,因为这是一个非常基于意见的问题。即使对于特定情况,也没有明确的正确/错误答案,更不用说一般情况了。我的回答是:最适合你的。这取决于。
-
但是,我认为值得一提的是选项 4:如果您只有一个
update操作,其中包含用于更新的白名单属性,并且每个表单只发送这些属性的子集,该怎么办?patch请求不需要是完整组参数;但仅限于您想要更改的内容。 -
@TomLord 我同意。我对在 StackOverflow 上回答有点陌生,但无论如何添加了一个答案。这种类型的问题通常在这里回答不好吗?
-
@DerekHopper 这样的问题通常以基于意见的方式结束,但我认为您的回答是您在这种情况下所能给出的最佳答案。我倾向于避免回答此类问题,但我认为您在这里的回答很有价值!
-
@TomLord 很公平。我意识到就“正确答案”而言,这可能有点边界。但我认为在一种行动方案可能比另一种更好的方面仍有待补充。同样关于您的选项 4,我确实需要至少以某种方式确定正在提交哪个表单,因为每个表单的实际 ajax 响应会略有不同。
标签: ruby-on-rails ruby forms crud