Rails:在RESTful控制器中将参数从new传递到create的“正确”(惯用)方法是什么?

时间:2010-02-08 18:23:44

标签: ruby-on-rails rest

我有一个非常常见的情况和解决方案,但我想问Rails专家是否可以改进。

我有一个非常典型的RESTful控制器,用户在创建时提供一些对象属性。有一个thing模型,一个ThingsController和各种视图,包括newcreate_form部分。

一件事有两个属性,

  1. 一种颜色,当它们点击链接创建它时设置(即“创建红色东西”链接,将红色ID编码为URL参数)
  2. 描述,由用户在表单视图中输入
  3. 我很满意处理属性的方法,例如用户在表单中指定的描述,但对我处理通过与第一个关联的URL参数传递的属性的方式不太自信单击。

    这就是我现在正在做的事情(注意我省略了错误检查以简化问题)。首先,控制器中的newcreate方法如下:

    def new
      @thing = Thing.new
      @thing.color = Color. find(params[:color])
    end
    
    def create
      @thing = Thing.new(params[:thing])
      @thing.color = Color. find(params[:color])
    
      if  @thing.save   
        flash[:notice] = "Successfully created thing."
        redirect_to somewhere_url
      else
        render :action => 'new'
      end
    end
    

    new视图只调用_form部分,如下所示:

    <% form_for @thing do |f| %>
      <%= f.error_messages %>
    
      <%= hidden_field_tag "color", @thing.color.id %>
    
      <%= f.label :description %>
      <%= f.text_area :description %>
      <%= f.submit "Submit" %>
    <% end %>
    

    通过在表单中​​放置隐藏字段,将颜色ID作为URL参数传递给create方法似乎有点混乱。这看起来是否合理,还是有其他方法会更好?

1 个答案:

答案 0 :(得分:3)

通常在这种情况下,我会在表单中放置一个隐藏字段,它将保存color_id。这种方式的好处是你可以在渲染表单之前设置对象的颜色。所以你的控制器改为:

def new
  @thing = Thing.new
  @thing.color = Color. find(params[:color])  
end

def create
  @thing = Thing.new(params[:thing])
  if  @thing.save   
    flash[:notice] = "Successfully created thing."
    redirect_to somewhere_url
  else
    render :action => 'new'
  end
end

,您的表单将更改为

<% form_for @thing do |f| %>
  <%= f.error_messages %>

  <%= f.hidden_field :color_id %>

  <%= f.label :description %>
  <%= f.text_area :description %>
  <%= f.submit "Submit" %>
<% end %>

然后颜色将通过两种形式,您只需要检索第一种形式的颜色。 (不要忘记添加你的Thing模型的验证,以确保它有一个有效的颜色。)