如何在Rails中将逻辑移出视图并进入控制器

时间:2012-07-18 21:29:59

标签: ruby model-view-controller view controller logic

我正在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'%>

我应该将该逻辑移动到控制器吗?我该怎么做呢?

3 个答案:

答案 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 @boardif @board != nil相同(除非您有@board false的特殊情况。nilfalse都会评估为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#showtopic#show的等效代码即可。您甚至可以执行@post = @board.posts.build,并且应该自动分配ID。