Form url not showing properly in rails - ruby-on-rails

I have this URL for my edit form :
<%=form_for #cad,:url =>{:action => "update",:controller => "cad" } do |f| %>
And it should point to "/cad/update",but the URL is pointing to "cad/6".
Please help.
Thanks in advance

it's perfectly fine if you follow restful routes for update it's a member route
There are 2 types of route
first one is collection route which will work on in general for all object like index action and second one is member route which will work on specific object like show,edit,update,destroy etc ,
In your case update is member route it has http verbs is put and it's basically post request
you can check http method
and You don't need url hash on form rails pick it routes based on object

Related

Can Ruby on Rails Routes point a nested URL at a single action?

Is it possible in Ruby on Rails (we're using v2 still) to allow the routes file to map a nested url EG
mydomain.com/controller/object/action
to a single action eg
:controller, :action
?
We currently have a url like
mydomain.com/controller/action
and i want to change it to
mydomain.com/controller/object/action
Thanks in advance
You can write singular route like as follow. You will get record id in params[:id] in controller action.
match 'controller/:id/action' => 'controller#action', via: :get

Invalid route name for GET and POST

I'm working through an older tutorial that was done for Rails 3. I'm using Rails 4.1.4.
One of the instructions is to change the routes file to include the following:
get '/boards/:board_id/conversations/:id/reply' => "conversations#reply", :as => :reply_board_conversation
post '/boards/:board_id/conversations/:id/reply' => "conversations#save_reply", :as => :reply_board_conversation
Obviously that gives me an error:
Invalid route name, already in use: 'reply_board_conversation'
It seems to me that the route is somehow trying to replicate the behaviour of a new and create action. Get for new and Post for create with a single route.
The problem is I can't figure out how to rewrite the route so it works. I've googled for solutions but can't seem to find anything. If anyone could point me in the right direction it would be hugely appreciated.
It looks like the only issue is with the duplicated "named route" name reply_board_conversation. So you could simply change one. I'd probably rename the save version to save_reply_board_conversation. Then it should work. Just remember to refer to the route this way in the future. This would primarily be used in a form tag. So, for exmaple:
<= form_tag :url => save_reply_board_conversation_path do %>
Note the use of save_reply_board_conversation_path instead of reply_board_conversation_path given that the form would be submitting a POST request instead of a GET request.
The names for these routes should be different although since the composition of the URL is the same so you really only need a name for the first one.
The trick with named routes is they generate the URL only, they do not set the HTTP request method. That has to be done independently.
That means you can call the same named route two different ways:
<%= link_to('View', board_path(#board)) %>
<%= link_to('Delete', board_path(#board), method: :delete) %>
These actually render as the same URL but one will hit the GET route, the other the DELETE one.

Ruby on Rails Routes Clarification

I'm not completely new to Ruby on Rails but it is not my most proficient framework so I was hoping someone could help me wrap my head around some code I'm trying to understand.
controller:
def new
#biz = Business.new
end
def apply
#biz = Business.new(business_params)
token = SecureRandom.hex(4)
#biz.verify_token = token
if #biz.save
message = #biz.sentMessages.new
message.send_verify_email
redirect_to waiting_verification_path
else
render 'new'
end
end
routes:
get 'apply', to: 'businesses#new', as: 'apply'
post 'apply', to: 'businesses#apply', as: 'applied'
view:
= simple_form_for #biz, url: apply_path, html: {autocomplete: "off"} do |f|
I understand that the first line of the routes directs a request at /apply to the new action in the controller which creates a new business object and renders the new view, which I have included a snippet from. This snippet includes the form action which directs a successful submission to the apply_path.
My understanding indicates that this apply_path is a named helper for the first routes line when I believe it should be directed to the second line, whose helper would be applied_path, and would then be handled by the apply action on the controller.
What is really causing me confusion is that this functionality works. So the submission is in fact being routed to the second routes line and being handled by the apply action in the controller. If you could explain how this is happening I would appreciate it tremendously. Thank you.
The line
= simple_form_for #bix, url: apply_path
generates something like
<form action="/apply" method="post">
..
</form>
POST is the default method on forms, so when the form is then POST-ed Rails looks at the routes.rb file and sees a match on this line.
post 'apply', to: 'businesses#apply', as: 'applied'
If however you had done it like this
= simple_form_for #bix, url: apply_path, method: :get
The form is submitted via GET and then Rails would find a match on the first line in routes.rb.
get 'apply', to: 'businesses#new', as: 'apply'
It doesn't matter what the name of the routes_helpers are, all that matters is the generated url. I hope that clears thing out, if not, just ask for more clarification.
The reason this is working is that you have two named routes that map to the same path. applied_path is /apply, and apply_path is /apply. These two named paths are IDENTICAL. The difference comes when the form performs a POST to /apply, it sees a POST and immediately goes to the second route. While a GET to that same /apply path will go to the first route.
On this note, you only really need to name one of the routes and just use that name everywhere. This is why, when you declare a resource in your routes file:
resources :users
You end up with a "POST /users" and a "GET /users" path which routes to users#create and users#index respectively, based on what kind of request was sent - BUT you only have one users_path named route, which always returns "/users"
The generated form will look like
<form action="/apply" method="post" autocomplete="off" class="simple_form new_business">
Note the method attribute: Because #biz is a new record, SimpleForm knows this should be HTTP POST'ed to the url specified (AFAIK persisted records will still create a method="post" on the form, but an additional hidden field with name="_method" and value="put" is inserted).
Since both route helpers, apply_path and applied_path, just generate the string '/apply', it does not matter which URL you define in your form. This should equally well work:
= simple_form_for #biz, url: applied_path, html: {autocomplete: "off"} do |f|
When you submit the form, your browser creates an HTTP request, like this:
POST /apply HTTP/1.1
<header information>
<post body>
and Journey (the Rails router module) will take the information POST + /apply to find the route to businesses#apply.
To make the route definition a little more concise, you could rewrite it as
scope as: :apply do
get '/apply', to: 'businesses#new'
post '/apply', to: 'businesses#apply'
end

How did Rails generate this path from our model and controller

Ok I kind of understand this part: CRUD verbs and actions http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
and if I go to the route file of the example I have, I also see a resources :orders in it.
But now in the view of a partial names _carts I am seeing this code:
<%= button_to "Checkout" , new_order_path, method: :get %>
What confuses me is the new_order_path ? Where did that come from? What Rails convention rule is allowing us to right this? Especially where did that "new" come from?
When you use resources :orders in the routes, Rails creates 7 routes for new, create, show, update, destroy, list, and edit. All of them are given names, and new_order_path/new_order_url is related to the new action.
These routes are described at the http://guides.rubyonrails.org/routing.html#paths-and-urls
Those path helpers are automatically generated for resources defined in your routes.rb. You can check what route helpers are available by executing rake routes at the command line. They are shown in the left-most column in the table that prints out.
The general pattern of the paths that are created are like so by default:
new_{singular form of resource}_path - Routes to new on GET
edit_{singular form of resource}_path - Routes to edit on GET
{singular form of resource}_path - Routes to show on GET, destroy on DELETE, update on PUT (Soon to be PATCH in Rails 4)
{plural form of resource}_path - Routes to index on GET and create on POST.
There's also helpers that end in _url instead of _path that provide absolute URLs instead of relative paths. The particular action that is hit in your controller depends on the HTTP verb (GET, PUT, POST, DELETE, etc.) used when visiting those URLs.

Submit a form to a Rails route with a dynamic segment

I have a route that looks like
match 'solar_systems/:planet_num/:moon_num' => 'solar_system#moon', :as => :moon
I'd like to have a form with a select box for planet number and moon number and have it submit to this route. However I cannot use moon_path because it will have an error if the dynamic parameters are not included in it like this moon_path(4, 1). Is what I want even possible? If so, what do I give to the form tag for the route?
You don't have to use the routing helper methods, and here you can't since at the time of rendering your form you do not know the required parameters. You do, however, know the controller and action, which is really all that's needed for the destination URL. So this should work:
= form_tag('/solar_systems/moon') do
= select_tag(:planet_num, ...
= select_tag(:moon_num, ...
This should render the form tag. To process the request, you will also have to add another route so the right controller action is called:
match 'solar_systems#moon' => 'solar_system#moon', :via => :post
Or, if it makes more sense in the context of your application, you could modify your existing route to make the parameters optional:
match 'solar_systems(/:planet_num(/:moon_num')) => 'solar_system#moon', :as => :moon
See this Rails guide for more details on non-resourceful routes.
If you use this params on controller you need to specified what params is each one, btw in you helper you need to do something like this
moon_path(planet_moon: 4, moon_num: 1)
Cheers!

Resources