Take the 2-minute tour ×

I am writing an imageboard in Ruby on Rails.

I have a form for creating new posts. In that form, there is logic to figure out whether the post was created from board#show or topic#show and act accordingly. It is:

  <% if @board != nil %>
    <%= f.hidden_field :board_id, :value => @board.id %>
  <% end %>

  <% if @topic != nil %>
    <%= f.hidden_field :topic_id, :value => @topic.id %>
  <% end %>

The form is rendered on board#show and topic#show with this piece of code:

<%= render :partial => 'posts/form'%>

Should I move that logic to the controller? How would I go about doing that?

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

As it is, in the view, it's probably fine. However, you could (possibly, depending on your app) refine it a little by putting the board/topic information in the URL using nested routes. Routes that would look something like this:


Then your "is it from a board or a post" logic could happen in your PostsController. Again, whether or not this is 'better' is dependent on your requirements, but that's an alternative way of approaching this.

As a side note, you can slim down your conditionals a little. if @board is the same as if @board != nil (unless you have a special case for @board being false. nil and false will both evaluate as false).

share|improve this answer
Your first idea wouldn't be too clean because I use the board title in the url, not the id. I ended up going with your second idea and just using if @board and keeping everything else. Thanks! –  DormoTheNord Jul 18 '12 at 22:30
add comment

I don't think it's necessary to put it in the controller. I would use :locals. So in board#show:

<%= render :partial => 'posts/form', :locals => {:resource => @board} %>

Do the same in topic#show, but using @topic. Then in your form partial:

<%= f.hidden_field "#{resource.model_name.downcase}_id", :value => resource.id %>

There are probably more elegant ways to get the model_name, but that's the direction I'd take it.

share|improve this answer
add comment

You should also consider a polymorphic relationship for this one. I'm not sure if it is a good fit, but it might be worth a try.

Otherwise, it's fine too pass nils. You can just do:

<%= f.hidden_field :board_id, :value => @board.try(:id) %>
<%= f.hidden_field :topic_id, :value => @topic.try(:id) %>

Come to think of it, ideally the controller should assign the fields to whatever you have in f and then the code should just be:

<%= f.hidden_field :board_id %>
<%= f.hidden_field :topic_id %>

Just do @post.board_id = @board.id in board#show and the equivalent code for topic#show. You can even do @post = @board.posts.build and that should assign the id automatically.

share|improve this answer
add comment

Your Answer


