Reputation: 999
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?
Upvotes: 2
Views: 401
Reputation: 3040
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.
Upvotes: 0
Reputation: 2923
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:
/boards/4/posts
/topics/133/posts
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).
Upvotes: 1
Reputation: 5301
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.
Upvotes: 1