我正在Ruby on Rails中编写imageboard。
我有一个用于创建新帖子的表单。在这种形式中,有一个逻辑可以确定帖子是从#show或topic#show创建并相应地执行的。它是:
<% if @board != nil %>
<%= f.hidden_field :board_id, :value => @board.id %>
<% end %>
<% if @topic != nil %>
<%= f.hidden_field :topic_id, :value => @topic.id %>
<% end %>
使用这段代码将表单呈现在#show和topic#show上:
<%= render :partial => 'posts/form'%>
我应该将该逻辑移动到控制器吗?我该怎么做呢?
答案 0 :(得分:1)
我认为没有必要把它放在控制器中。我会用:locals
。所以在board#show
:
<%= render :partial => 'posts/form', :locals => {:resource => @board} %>
在topic#show
中执行相同操作,但使用@topic
。然后在你的形式部分:
<%= f.hidden_field "#{resource.model_name.downcase}_id", :value => resource.id %>
获取model_name可能有更优雅的方法,但这是我采取的方向。
答案 1 :(得分:1)
事实上,在视图中,它可能很好。但是,您可以(可能,取决于您的应用程序)通过使用嵌套路由将板/主题信息放在URL中来稍微改进它。路线看起来像这样:
/boards/4/posts
/topics/133/posts
然后您的“是来自电路板还是帖子”逻辑可能会发生在您的PostsController中。同样,这是否“更好”取决于您的要求,但这是一种替代方法。
作为旁注,你可以稍微减轻你的条件。 if @board
与if @board != nil
相同(除非您有@board
false
的特殊情况。nil
和false
都会评估为false )。
答案 2 :(得分:0)
您还应该考虑这个的多态关系。我不确定它是否合适,但值得一试。
否则,通过nils就好了。你可以这样做:
<%= f.hidden_field :board_id, :value => @board.try(:id) %>
<%= f.hidden_field :topic_id, :value => @topic.try(:id) %>
考虑一下,理想情况下,控制器应该将字段分配给f
中的任何字段,然后代码应该是:
<%= f.hidden_field :board_id %>
<%= f.hidden_field :topic_id %>
只需@post.board_id = @board.id
中的board#show
和topic#show
的等效代码即可。您甚至可以执行@post = @board.posts.build
,并且应该自动分配ID。