【问题标题】:How to prevent polluting a rails object when using form_for and .new?使用 form_for 和 .new 时如何防止污染 rails 对象?
【发布时间】:2012-05-31 11:32:46
【问题描述】:

我有一个模型:

class Activity < ActiveRecord::Base
    has_many   :activity_states
end

我想为新的活动状态呈现选项并呈现现有的活动状态。但是,当我使用这个 form_for 时:

<%= form_for activity.activity_states.new, :remote => true do |f| %>
    <%= f.hidden_field :state_type, :value => activity_state_type %>
    <%= f.hidden_field :activity_id %>
    <%= f.submit submit_label, :disable_with => 'sending...' %>
<% end %>

为了创建新的临时 activity_state 模型以用作新 activity_states 的基础,它会使用 nil 活动状态污染活动对象,因此而不是 Activity 具有活动状态:

[#<ActivityState id: 7353, activity_id: 2033, state_type: 0, created_at: "2012-05-31 11:06:50">, 
#<ActivityState id: 7354, activity_id: 2033, state_type: 1, created_at: "2012-05-31 11:06:53">, 
#<ActivityState id: 7355, activity_id: 2033, state_type: 2, created_at: "2012-05-31 11:06:59">]

由于.new

#<ActivityState id: nil, activity_id: 2033, state_type: nil, created_at: nil>

导致:

[#<ActivityState id: 7353, activity_id: 2033, state_type: 0, created_at: "2012-05-31 11:06:50">, 
#<ActivityState id: 7354, activity_id: 2033, state_type: 1, created_at: "2012-05-31 11:06:53">, 
#<ActivityState id: 7355, activity_id: 2033, state_type: 2, created_at: "2012-05-31 11:06:59">,
#<ActivityState id: nil, activity_id: 2033, state_type: nil, created_at: nil>,
#<ActivityState id: nil, activity_id: 2033, state_type: nil, created_at: nil>]

当我遍历活动的活动状态并渲染它们时,这会搞砸事情。我尝试了一种巧妙的方法来解决这个问题:在每个 form_for 之后使用:&lt;% activity.activity_states.pop %&gt; 但这在 Heroku 上生产时不起作用,因为它抱怨试图修改冻结的数组。

请对“正确”的做法有任何想法吗?我知道我在这里没有理解一些非常基本的东西,也知道我通过为 id 字段 (which can then be manipulated by malicious users) 插入一个隐藏字段打开了一个漏洞。

【问题讨论】:

  • 为什么需要创建临时活动状态?在模型中这样做会更好。您正在苦苦挣扎,因为您将业务逻辑与视图层混合在一起。所有业务逻辑都属于模型。这需要进一步讨论 - 查看我的个人资料以获取 Rails 论坛的链接并在其中发帖,因为您无法在 stackoverflow 中进行讨论。
  • 嗨@jamesw,非常感谢您的评论。我还没有对此采取行动,因为我还没有回到这个项目。当我这样做时,我一定会在 Rails 论坛上发布它。干杯。

标签: ruby-on-rails-3 form-for


【解决方案1】:

到目前为止,我有一个解决方案,在activity controllershow 方法中,包括:

@new_activity_state = @activity.activity_states.new
@activity.activity_states.pop

在部分视图中(我将 @activity 作为局部变量 activity 传递):

<% new_activity_state = @new_activity_state || activity.activity_states.new %>
<%= form_for new_activity_state, :remote => true do |f| %>
    <%= f.hidden_field :state_type, :value => activity_state_type %>
    <%= f.hidden_field :activity_id %>
    <%= f.submit submit_label, :disable_with => 'sending...' %>
<% end %>

Heroku 的生产环境现在不反对 .pop,这很棒 :D 但是有更好的方法吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 2021-01-12
    • 2020-08-22
    • 1970-01-01
    • 2018-11-29
    相关资源
    最近更新 更多