我有一个非常常见的情况和解决方案,但我想问Rails专家是否可以改进。
我有一个非常典型的RESTful控制器,用户在创建时提供一些对象属性。有一个thing
模型,一个ThingsController
和各种视图,包括new
,create
和_form
部分。
一件事有两个属性,
我很满意处理属性的方法,例如用户在表单中指定的描述,但对我处理通过与第一个关联的URL参数传递的属性的方式不太自信单击。
这就是我现在正在做的事情(注意我省略了错误检查以简化问题)。首先,控制器中的new
和create
方法如下:
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
方法似乎有点混乱。这看起来是否合理,还是有其他方法会更好?
答案 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模型的验证,以确保它有一个有效的颜色。)