How do you update a nested has_one resource? - ruby-on-rails

I seem to have two problems
1) While trying to update my singular nested resource
Restaurant has_one Hour
and
Hour belongs_to Restaurant
resources :restaurants do
resource :hour
end
with an edit link on my restaurant show page called:
<%= link_to 'Set Hour', edit_restaurant_hour_path([#restaurant, #restaurant.hour]) %>
and the edit page has a partial render that looks like:
<%= render :partial => 'restaurants/hours', :locals => { :hour => 'hour' } %>
which loads a partial named _hours.html.erb:
<%= form_for hour do |f| %>
<div class="row-fluid">
<div class="span1 hours_input">
<h3>Monday</h1>
From
<%= f.text_field :from_monday, :class => 'span20 hour_field' %>
To
<%= f.text_field :to_monday, :class => 'span20 hour_field' %>
</div>
<div class="span1 hours_input">
<h3>Tuesday</h3>
From
<%= f.text_field :from_tuesday, :class => 'span20 hour_field' %>
To
<%= f.text_field :to_tuesday, :class => 'span20 hour_field' %>
</div>
<div class="span1">
<%= f.submit 'Set Hours' %>
</div>
</div>
but once I press the submit button it gives me the error:
No route matches [POST] "/restaurants/34/hour/edit"
I tried setting it as:
<%= form_for hour, :method => put, :html => { :action => 'update' } do |f| %>
but with no luck.
Any help would be greatly appreciated!
I'm using rails 3.2.3
2) My second problem is rather mysterious.
Once I press on the button
<%= link_to 'Set Hour', edit_restaurant_hour_path([#restaurant, #restaurant.hour]) %>
on the restaurant show page, it'll give the url:
http://localhost:3000/restaurants/34//hour/edit
with the double slash before //hour. I suspect this will break in production but doesn't seem to affect me in development.
Again, thanks for reading and have a good one!
Edit: Here's the rake routes--
restaurant_hour POST /restaurants/:restaurant_id/hour(.:format) hours#create
new_restaurant_hour GET /restaurants/:restaurant_id/hour/new(.:format) hours#new
edit_restaurant_hour GET /restaurants/:restaurant_id/hour/edit(.:format) hours#edit
GET /restaurants/:restaurant_id/hour(.:format) hours#show
PUT /restaurants/:restaurant_id/hour(.:format) hours#update
DELETE /restaurants/:restaurant_id/hour(.:format) hours#destroy
restaurants GET /restaurants(.:format) restaurants#index
POST /restaurants(.:format) restaurants#create
new_restaurant GET /restaurants/new(.:format) restaurants#new
edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
restaurant GET /restaurants/:id(.:format) restaurants#show
PUT /restaurants/:id(.:format) restaurants#update
DELETE /restaurants/:id(.:format) restaurants#destroy
hour GET /:restaurant/hour(.:format) hours#show
POST /:restaurant/hour(.:format) hours#create
hour_add GET /:restaurant/hour/add(.:format) hours#new
hour_edit GET /:restaurant/hour/edit(.:format) hours#edit

I figured it out, but it's apparently not the RESTful way to do it.
I just had to add:
<%= form_for hour, :url => { :action => "update" }, :html => { :method => 'put' } do |f| %>
and specify the action/method for the update to work.
Another post suggested that just using:
<%= form_for #hour do |f| %>
would have worked, too, but I wasn't having any luck with that for some reason.

Related

Rails - Silmple Form calls a specified action of my user controller

My problem is that when i try to call a specified method from a simple_form_for form it doesn't work.
Here is my code :
<%= simple_form_for #user, :url => {:action => :register_iban}, :html => { :method => :post } do |f| %>
<div class="col-md-8">
<%= f.input :first_name, :label => t('user-show.payment.form.first_name'), placeholder: "Prénom" %>
<%= f.input :last_name, :label => t('user-show.payment.form.last_name'), placeholder: "Nom" %>
<%= f.input :iban, :label => t('user-show.payment.form.iban'), placeholder: "IBAN" %>
<%= f.input :bic, :label => t('user-show.payment.form.bic'), placeholder: "BIC" %>
</div>
<div class="col-md-8 text-center">
<%= f.submit t('user-show.payment.title'), class: 'btn btn-danger' %>
</div>
<% end %>
So, as you can see, i try to call register_iban method from my user controller.
But when i do that, i have an error : No route matches {:action=>"register_iban", :controller=>"users", :id=>"5", :locale=>nil}
Everytime i create a new method in a controller, i have to create a route in the routes.rb file ? Here, i'd like to make this url : /users/5/register_iban (where "5" is the user id) call my method.
Sorry but i start in ruby and i'm pretty stuck :/
in your config/routes.rb try to add in the users resources
resources users do
member do
post :register_iban
end
end
No route matches {:action=>"register_iban", :controller=>"users", :id=>"5", :locale=>nil}
This error means you're trying to access a route which doesn't exist.
The routes are defined at config/routes.rb:
#config/routes.rb
resources :users do
post :register_iban
end
This will allow you to call the register_iban method in the users controller through your form.
You'll also want to make sure you're calling routes with the appropriate helpers:
<%= simple_form_for #user, url: user_register_iban(#user) %>

Do not post a form in a Rails root route

I have a controller with just one method:
index_controller.rb
def index
# some code
end
The form:
index.html.erb
<%= form_tag :class => "form-inline signup" do %>
<div class="form-group">
<%= text_field_tag :url, nil, :class => "form-control", :placeholder => "URL do tópico" %>
</div>
<%= submit_tag "Enviar", method: :post, :class => 'btn btn-theme' %>
<% end %>
And a simple root route:
root 'index#index'
post '/', to: 'index#index'
The problem is that when I load the root page, the form is posted automatically, when the preferable was to POST just on the button call.
What am I missing here?
You should move the code for the post out to another action that can handle that.
post '/', :to => "index#submit"
Then you can define a submit action within your IndexController to handle the form, and the index action won't run the form code anymore.

Rails 3: Can't add correct route to legacy code

Believe you can help me.
I'm trying to add new functionality to legacy code (Typo). But it seems that there is some problem about routing.
In the project routes are generated the following way:
%w{advanced cache categories comments content profiles feedback general pages
resources sidebar textfilters themes trackbacks users settings tags redirects seo post_types }.each do |i|
match "/admin/#{i}", :to => "admin/#{i}#index", :format => false
match "/admin/#{i}(/:action(/:id))", :to => "admin/#{i}", :action => nil, :id => nil, :format => false
end
My functionality is about merging articles. For that I've added new action in the /admin/content controller:
def merge
#some code here
end
A piece of a view partial (_form.html.erb) added by me:
<% if current_user.admin? and !#article.id.nil?%>
<div class=''>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %><%= text_field_tag :merge_with, nil, :size => 20 %>
<%= button_to 'Merge', admin_content_merge_path(:id => #article.id) %>
</div>
<%end%>
This partial is rendered by another partial (_edit.html.erb)
<%= form_tag(form_action, :id => "#{form_type}_form", :enctype => "multipart/form-data", :class => className) do %>
<%= render :partial => "form" %>
<% end %>
And finally _edit.html.erb is rendered by view new.html.erb
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
The problem is how to write a correct route for the controller action above which will allow me to render an edit page containing newly merged article. I wrote:
match "/admin/content/merge/:id" => "admin/content#merge",:as => 'admin/content/merge'
rake routes output:
admin_content_merge /admin/content/merge/:id(.:format) {:controller=>"admin/content", :action=>"merge"}
But the new or edit action is being invoked as I can see.
Apparently, my route is wrong, isn't it?
Could you please help me with this.
Thanks in advance!
Update
Up-to-date new.html.erb:
<% #page_heading = _('New article') %>
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
<% if current_user.admin? and !#article.id.nil?%>
<%= form_tag "/admin/content/merge/#{#article.id}" do %>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %>:
<%= text_field_tag :merge_with %><br />
<%= submit_tag "Merge" %>
<% end %>
<% end %>
Read the hint from the course:
HINT:Nesting is invalid in HTML.
That means that you can't nest form tags, don't put the form tag in another form tag, your nested form wont be able to do a correct action.
Since you have to put your code at the end of the page, try and see how to do it with having your merging form tag below the main edit article form tag. So basically you can find where the big form tag ends and put it below it.
Try to see if you can figure it out, and if not, don't hesitate to ask :)
Btw. I think everybody had some problem with this

Rails 3 - button_to update same page with controller#method

In my project I have the following form_tag to select a Site
<%= form_tag({:controller => "hvacs", :action => "index"}, :method => "get") do %>
<div class="field">
<%= select :p, :site_sel, #user_sites.map{|s| [s.name, s.id]} %>
</div>
<div class="actions">
<%= submit_tag("Select site") %>
</div>
<% end %>
This form_tag updates the index page through calling its method in the controller again.
I have the following button_to
<td><%= button_to 'Select', {:controller => "hvacs", :action => "select"}, :method => "get" %></td>
I would like to achieve a similar update with this as above rather than redirect to a new page with "select_path" etc, but the above does not seem to work.
How can I achieve this? Cheers!
OK, this looked so much like my AJAX problem, I tried to make it one!
I think all you need is a simple render statement in your select action
render :index
or
render :action => 'index'
But see http://guides.rubyonrails.org/layouts_and_rendering.html#using-redirect_to for more.
The following solution worked. Apologies if I was not so clear on what I was looking for.
<%= button_to 'Select', review_hvacs_path(:h => hvac, :a => params[:a], :s => params[:s]) %>
I was trying to pass parameters with the button, while staying on the review page.

rails admin edit view path routes

I've got an admin section setup, but am having trouble getting the "update" route to work.
Getting error when hitting "update" via the edit view:
"No action responded to 2."
For some reason the route is responding to the :id as the :action.
Parameters:
Parameters: {"commit"=>"Update", "action"=>"2", "_method"=>"put", "admin"=>{"ended_at(1i)"=>"2010", "ended_at(2i)"=>"8", "ended_at(3i)"=>"22"}, "id"=>"edit", "controller"=>"admin/subscriptions"}
The edit view uri:
/admin/subscriptions/2/edit
Edit view:
<% form_for :admin, #subscription, :html => {:method => :put} do |f| %>
<p>
<%= f.label :ended_at %><br />
<%= f.date_select :ended_at %>
</p>
<p>
<%= f.submit 'Update' %>
</p>
<% end %>
Route:
map.namespace :admin do |admin|
admin.resources :subscriptions
end
I assume I need to do something differently in the form_for method or maybe the routes, but everything I've tried isn't working.
Thanks for the help!!
It should be this:
<% form_for [:admin, #subscription] do |f| %>
By putting :admin and #subscription in square-brackets, this makes it into an array which is passed as the first argument to form_for. The benefit of this is if #subscription is a pre-existing record (as-in, one found by find, not created with new) then Rails will know to set the form method to PUT.
This works:
<% form_for :admin, #subscription, :html => {:method => :put}, :url => { :action => "update" } do |f| %>
Seems verbose though. Any better ideas?
Try
- form_for :subscription, #subscription do |f|
We're using formtastic here.

Resources