Multiple Rails view links, each performing a different action - what's the best way to handle this?

One of the things I do is include multiple links in the view to show . For example, I have a link (or button) for "Accepting" and another for "Decline". Click Accept and the model will update the is_accepted field as true, click Reject and the is_accepted field will be false.

Now how can I best deal with it? In ASP.NET I would just create a LinkButton and write a handler, but Rails doesn't work that way, so I'm trying to figure out how to essentially replicate what the LinkButton will do.

I am currently coding two forms on the same view, almost the same, that look like this:

<%= form_for @thing do |f| %>
  <%= hidden_field_tag 'thing[is_accepted]', '1' %>
  <%= f.submit "Accept" %>
<% end %>
<%= form_for @thing do |f| %>
  <%= hidden_field_tag 'thing[is_accepted]', '0' %>
  <%= f.submit "Reject" %>
<% end %>

      

This seems strange to me, but I can't find anything that says that this is the wrong way to do it.

I could, in my opinion, dry things using a partial and / or auxiliary method, but I wanted to make sure that I was on the right track and not doing something completely wrong.

+1


source to share


4 answers


I think you are on the right track. One way to clean up your forms is with form model helpers to the end, so you end up with something like

<%= form_for @thing do |f| %>
  <%= f.hidden_field :accepted, :value => true %>
  <%= f.submit "Accept" %>
<% end %>

<%= form_for @thing do |f| %>
  <%= f.hidden_field :accepted, :value => false %>
  <%= f.submit "Reject" %>
<% end %>

      



But other than that, it looks like the right way. I suggest not creating new methods for this, because you are not doing anything outside of normal web requests (updating the model in this case).

Using the submit tag as a toggle and detecting it in the [] parameters is also a good way to go, but I usually prefer to keep my controllers as vanilla as possible. In the end, both of these ways will end up with the same amount of "stuff" in the user interface, so whichever style you use should be fine.

+1


source


You can specify your submit name tag .. ie

<%= form_for @thing do |f| %>
  <%= hidden_field_tag 'thing[is_accepted]' %>
  <%= f.submit "Accept", :name => 'accept' %>
  <%= f.submit "Reject", :name => 'reject' %>
<% end %>

      



Then you can define the name in parameters [] and skip the value "1" / "0".

+2


source


Depending on how you want your UI to work, you might want to think about link_to_remote (part of the prototype helper) - you can specify an action, parameters, etc., and return JS to it that runs.

0


source


If you are using map.resources in your routes.rb you should do something like this:

map.resources :things, :member => {:accept => :get, :reject => :get}

      

Then in your controller:

def accept
  @thing = Thing.find(params[:id])
  @thing.is_accepted = true
  @thing.save
end

def reject
  @thing = Thing.find(params[:id])
  @thing.is_accepted = false
  @thing.save
end

      

And finally, in your opinion:

<%= link_to 'Accept', accept_thing_url(@thing) %>
<%= link_to 'Reject', reject_thing_url(@thing) %>

      

Or, if you are using Ajax:

<%= link_to_remote 'Accept', :url => accept_thing_url(@thing) %>
<%= link_to_remote 'Reject', :url => reject_thing_url(@thing) %>

      

-1


source







All Articles