Routing issue. Url becomes parameter - ruby-on-rails

I have a url with path /user_management/edit_official/:id
its corresponding output from rake routes is
user_management_update_official POST /user_management/edit_official/:id(.:format) {:controller=>"user_management/employees", :action=>"update_official"}
When I try to access url via form, url is not reached, because the url /user_management/edit_official/:id becomes a parameter.
Following is the log file entry?
Started POST "/user_management/edit_official/31" for 127.0.0.1 at
2012-01-02 11:05:21 +0530 Processing by ErrorsController#index as
HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"DED4E/9w/GDUQdjZ27mrUWrYBgipgHnNvS8mOjdaNXU=",
"employee"=>{"empl_id"=>"", "confirmation_date"=>"",
"designation_id"=>"", "rep_head1_id"=>"", "payment_mode"=>"",
"pf_number"=>"", "bank_name"=>"", "pt_applicable"=>"false",
"reg_date"=>"", "employee_type_id"=>"", "joining_date"=>"",
"rep_head2_id"=>"", "pf_applicable"=>"false",
"bank_account_number"=>"", "empl_email_id"=>"false",
"last_working_date"=>""}, "designation_level"=>"L-5b",
"user"=>{"username"=>"dsaf.adsfas", "password"=>"[FILTERED]"},
"commit"=>"Next", "a"=>"user_management/edit_official/31"}
Is there any reason for this. Thanks.
EDIT: Form included
<% url = user_management_update_official_path(#employee) %>
<%= form_for(#employee, :url => url, :html => { :enctype => 'multipart/form-data'} ) do |f| %>
<div id="employee_details" class="employee_form_steps">
<%= render :partial => 'user_management/employees/official_information',
:locals => { :f => f} %>
</div>
<div class="btn_row">
<%= content_tag(:button, '< Back', :id => 'official_information_back', :class => 'grey') %>
<%= f.submit 'Next', :class => 'green', :style => 'margin:0px;padding:4px;width:50px;' %>
<%= content_tag(:button, 'Cancel', :class => 'cancel grey') %>
</div>
<% end %>

The error must lie in your routes.rb
The rule in this file is: first match, first served.
Try to take the line corresponding to "errors#index" and put it under the one describing /user_management/edit_official/:id

The actual problem was the http method used for form. The form_for used put method while, in routes I specified POST. Changing POST to PUT, made everything work.

Related

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

How do you update a nested has_one resource?

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.

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.

Loading a template via Ajax - Error

I have this form that I want to load via AJAX into the video show view:
<%= form_for #video, :url => {:action => "update"}, :remote => true do |f| %>
<div class="field">
<%= f.text_field :topic_names, :class => "topic_field" %>
</div>
<%= f.submit "Add Topic" %>
<% end %>
I have this link in the video show view that when clicked, I want it to render the form:
<%= link_to "Add Topics", new_topicable_path(#topicable, :format => :js), :remote => true, :id => 'edit_topics_link' %>
I put the form in topicables/new.html.erb and I have topicables/new.js.erb file which has:
$("<%= escape_javascript render(:file => 'topicables/new.html.erb') %>").insertAfter('.topic_holder');
$('#edit_topics_link').hide();
Now when I click the link, I get an error in my logs. This is what my logs show:
Started GET "/topicables/new.js" for 127.0.0.1 at Sat Apr 02 03:58:52 -0700 2011
Processing by TopicablesController#new as JS
Rendered topicables/new.html.erb (0.7ms)
Rendered topicables/new.js.erb (2.6ms)
Completed in 15ms
ActionView::Template::Error (undefined method `model_name' for NilClass:Class):
1: <%= form_for #video, :url => {:action => "update"}, :remote => true do |f| %>
2: <div class="field">
3: <%= f.text_field :topic_names, :class => "topic_field" %>
4: </div>
app/views/topicables/new.html.erb:1:in `_app_views_topicables_new_html_erb___1876131309_2172772700_0'
app/views/topicables/new.js.erb:1:in `_app_views_topicables_new_js_erb__1367015167_2172792200_0'
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.4/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (92.5ms)
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.4/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (98.9ms)
What's going on? How can I fix this error to make the AJAX rendering of the form work?
This is basically telling you that #video is not defined. If that's the case you can either define it in your new method or use :video which creates a new instance variable rather than looking for one in the page context. Then you can handle the find and update in the update method.
Edit: jQuery load method
$("#myButton").click(function(){
$("#target").load("/topicables/new #new_topicable");
});

Resources