Small form to move associations - ruby-on-rails

I've got a group which has many clients.
The moment the user wants to delete the group, he's obligated to move the clients of that group to a different group.
So i've created a little form. But I already know it's wrong. but I don't know how I should do it otherwise.
I want the form to be caught by my disband_group method in my groups controller. Extract the move_to ID etc.
This is what I have now. Which doesn't work.
(it says param not found: group on params.require(:group) which is no big surprise)
<%= form_for(#group) do |f| %>
<%= select_tag('move_to', options_for_select(current_user.groups.collect{ |u| [u.name, u.id] }), :prompt => "Choose") %>
<%= f.submit "Move" %>
<% end %>

The select_tag needs to be changed to f.select. That should do the trick.
After that if it still does not work, put a 1/0 as the first line in the method to check the parameters coming in. This will throw an exception and the page will display the parameters.

Add a route to your disband_group action (add the correct path):
post '/disband_group' => "groups#disband_group", :as => :disband_group
And then modify your form pointing to the disband_group action:
<%= form_for(:group, url: disband_group_path) do |f| %>
<%= f.select :move_to, options_for_select(current_user.groups.collect{ |u| [u.name, u.id] }), :prompt => "Choose") %>
<%= f.submit "Move" %>
<% end %>
This will add send the move_to param as follows: "group" => { "move_to" => "3" }
Take a look to this to understand how the form works.

Related

Change URL by filter

I am using friendly_id so that I can create such URLs:
/search/france/weekly/toyota-95
My routes:
scope to: 'search#show' do
get '/search/:car_country_id/:rental_type_id/:car_group_id', as: 'search_country'
end
At the search#show view I have a form:
<%= form_tag search_country_path, :method => :get do %>
<%= select_tag(:car_country_id, options_from_collection_for_select(CarCountry.all, :slug, proc {|c| c.name }, {:selected => #country}), class: "Select-control u-sizeFull") %>
<%= submit_tag t('shared.search'), class: 'btn btn-primary' %>
<% end %>
And search controller:
#country = CarCountry.friendly.find(params[:car_country_id])
So ok, my intention is to change the URL as:
/search/italy/weekly/toyota-95
But the thing is, Rails params always sending france as car_country_id when I select country from select tag and submit it.
So what should I do?
Currently, two car_country_id are sent to Rails server. You can rename one of them:
<%= select_tag(:new_car_country_id, options_from_collection_for_select(CarCountry.all, :slug, proc {|c| c.name }, {:selected => #country}), class: "Select-control u-sizeFull") %>
In your controller, you should check whether new_car_country_id exists. If it does, then redirect to the corresponding path.
Another way is to make sure that the two car_country_id are the same. You should change the form's submit path once select_tag is updated with JavaScript.

What's the Rails Way to pass data to controller method?

After getting some data from an API, I filtered the results and showed them on a view to et the user select which data he wants to save to the database. The user doesn't have to fill anything once all the data came from the API.
My question is: what's the best way/rails way to pass all this data to the controller?
Right now I'm using a form with hidden fields. It works but I was wondering if that's the best way.
Here's how my 'form_for' looks like:
<%= form_for (#new_photoset) do |f| %>
<%= f.hidden_field :id, :value => not_imported_set.id %>
<%= f.hidden_field :name, :value => not_imported_set.name %>
<%= f.hidden_field :thumb_url, :value => not_imported_set.url) %>
<%= f.submit "Import" %>
<% end %>
I believe you're on the right track, this is way you would normally do this in rails.

rails form_tag url path

This seems like it should be so simple but it has been causing me issues.
I have a select_tag that pulls from a model. All I want to is have a person choose their location from the drop down, press submit and take it to that places page.
Here is what I have
<% form_tag installation_path do %>
<%= select_tag :id, options_from_collection_for_select(Installation.find(:all), :id, :name) %>
<div id="button">
<p>
<%= submit_tag "Go", :name => nil %>
</p>
</div>
The problem is it of course wants an :id but it won't pull the :id from the drop down menu below.
What am I doing wrong, any other suggestions on the "right" way to do this.
Thanks
Looks like you actually want to GET, not to POST the params.
form_tag installation_path, :method => :get do

Rails: Using form (collection select) to call show-action

A model named 'book' with attributes 'name' and 'id' is given. How can i use this collection select to call the show-action of a certain book? The one code mentioned below returns the following error message:
Couldn't find Book with ID=book_id
<% form_tag(book_path(:book_id)), :method => :get do %>
<p>
<%= label(:book, :id, 'Show Book:') %>
<%= #books = Books.find(:all, :order => :name)
collection_select(:book, :id, #books, :id, :name)
%>
</p>
<p>
<%= submit_tag 'Go' %>
</p>
<% end %>
book_path is generated once only, for the form tag itself. It won't be updated whenever your selection changes.
When you submit that form, it's going to request the following URL:
/books/book_id?book[id]=5
Since your book_path thinks book_id is the ID number you wanted, it tries to look that up. You could do what you want you by changing the code in your controller from:
#book = Book.find(params[:id])
to:
#book = Book.find(params[:book][:id])
But it kind of smells bad so be warned.
You can create a new route that is not based on the id, like
get 'books/show' # put this above your "resources :books"
and change your form to
<% form_tag books_show_path, :method => :get %>

Multiple links on a Rails view that each perform different actions - how best to handle this?

One of the things I'm doing includes several links on the show view. For instance, I have a link (or button) for "Accepting", and another one for "Rejecting". Click on Accept, and the model updates the is_accepted field as true, click on Reject, and the is_accepted field is false.
Now, how best do I handle this? In ASP.NET, I would have simply created a LinkButton and written a handler, but Rails doesn't work that way, so I'm trying to figure out how to essentially replicate what a LinkButton would do.
Right now, I'm coding two forms on the same view, nearly identical, 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 feels weird to me, but I can't seem to find anything that says this is the wrong way to do it.
I could, I assume, dry things up by using a partial and/or a helper method, but I wanted to make sure I'm on the right track and not doing something totally wrongly.
You can give your submit tag a name.. 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 detect the name in params[] and skip the '1'/'0' value.
I think you're going about it the right way. One way to clean up your forms is by using the model form helpers all the way through, so you'd 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 to go about it. I would suggest against creating new methods to do this, because you're not doing anything outside of normal web requests (updating a model in this instance).
Using the submit tag as the switch and detecting it in params[] is also a good way, but I usually prefer to keep my controllers as vanilla as possible. In the end, both of these ways would end up with the same amount of 'stuff' in the UI, so whichever style you'd rather use should be fine.
Depending on how you want your UI to work you might consider link_to_remote (part of the prototype helper) - you can specify an action, params etc, and have it return some JS that gets run.
If you're using map.resources in your routes.rb you should be able to 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 view:
<%= 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) %>

Resources