add get parameter to helper methods - ruby-on-rails

I added the following line in config/routes.rb file :
get '/movies/similar', :contoller => 'movies', :action => 'similar'
I see that there is a helper method with name 'movies_similar_path'. I want to add a get parameter to 'movies_similar_path' with name 'director' so I can get '/movies/similar?director=someone'
How can I do it?

No need to define parameter in the helper, you can assign it in the link_to.
link_to "Similar", movies_similar_path(:director => #director.id)

noticed the typo in 'controller' in your routes line?
What you want, you do in the form of page you are calling by adding a hidden field, or putting the extra fields in the 'link_to'. Like "link_to "simsforthisdirector", movies_similar_path(#movie), :director=>#director.name
See: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
Especially the examples will help you out.

If you are using rails 3 then you can declare route as -
get '/movies/similar(/:director)', :to => 'movies#similar'
and while using you can use it as -
movies_similar_path
or
movies_similar_path(#director.name)

Related

Why did Ruby on Rails' URL Helper put a period in my URL?

I have the following code in my view (RoR 4):
tbody
- #order_submissions.each do |order_submission|
tr
td = order_submission.id
td.table-actions
span = link_to "Show", order_submissions_path(order_submission.id)
td = order_submission.id
successfully displays as the ID number (533ab7337764690d6d000000)
But...
order_submissions_path(order_submission.id)
Creates a URL that comes out as:
order_submissions.533ab7337764690d6d000000
I want it to be
order_submissions/533ab7337764690d6d000000
Where did that period come from?
This is my route:
get 'order_submissions/:id' => 'order_submissions#show'
And when I run rake routes I get:
GET /order_submissions/:id(.:format) order_submissions#show
The (.:format) is probably what's messing it up but I don't know why. I just want it to put a slash in there.
If I change my code to this it fixes it:
span = link_to "Show", order_submissions_path + '/' + order_submission.id
But that's a really, really stupid workaround.
EDIT: Here are my routes:
get 'order_submissions' => 'order_submissions#index'
get 'order_submissions/new' => 'order_submissions#new'
post 'order_submissions' => 'order_submissions#create'
get 'order_submissions/:id' => 'order_submissions#show'
get 'order_submissions/:id/edit' => 'order_submissions#edit'
patch 'order_submissions/:id' => 'order_submissions#update'
get 'order_submissions/:id/delete' => 'order_submissions#delete'
delete 'order_submissions/:id' => 'order_submissions#destroy'
The order_submissions_path (plural) points to /order_submissions. It takes two arguments, the first being the format for the request (e.g. html). Your ID is being passed in for this argument, leading to the resulting URL you're seeing.
You actually want the singular path helper, order_submission_path, which accepts an ID as the first argument.
Because it should be a singular form:
order_submission_path(order_submission.id)
Not
order_submissions_path(order_submission.id)
order_submissions_path points onto index action. You can also remove id from the end.
UPDATE:
Just notice you route file. Do you have any resources defined there? The route you posted wouldn't generate any url_helper as you dind't specify route name (most likely this entry is obsolete, as I expect there is resources :order_submissions somewhere there as well).
You don't get a named route by default. The route you showed from rake routes doesn't list a named route, for example.
GET /order_submissions/:id(.:format) order_submissions#show
Normally, you'd see the named route in front of GET there.
So you can define it yourself and then your route will work:
get 'order_submissions/:id' => 'order_submissions#show', as: :order_submission
Notice the as: :order_submission bit. Now, order_submission_path(order_submission.id) will work. (Note: .id is superfluous if your order_submission responds to to_path and returns id.)
I'm guessing you have another route in your rake routes output that uses the named route you supplied and that doesn't use /:id. Perhaps your index route?

How to create rails route with constrants for numbers-only that accepts empty parameter?

I have created some route like this:
get 'foo/:offset' => 'foo#action', :as => :foo, :constraint => { id: /\d+/ }
It works fine, but: I want rails to route /foo to foo#action if no parameter specified, so not only urls like /foo/123 will be routed but simple /foo too.
How can I change constraint for this? Thanks for help!
I don't know if this is the best solution, but it's a simple one:
Create a route for /foo, and another for /foo/:offset to the same controller and action!

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!

Do you have to define controller helpers to get paths for new routes in rails?

I have a Customer model and I want his controller to repond to a find method
I added this in my routes.rb file:
match 'customers/find/:name' => 'mymodel#find' resources :customers
In my controller I have something like this:
def find
#customers = Customer.fin_all_by_name(params[:name])
end
in my views, when I need to create a link for that resource I'm using this:
= link_to 'Find By Name', :controller => "customers", :action => "find", :name => #customer.name
now, I'm trying integration tests with cucumber and I have a problem: I have to create a step definition in my customer_step.rb file for customers having same name:
when /^customers having same name as "(.*)"/
url_encode('/customers/find/' + $1)
now that line doesn't work, it says undefined method `url_encode'
I need to encode that string because if the name contains a space I get obvious errors.
I'm new to ruby and rails and I think I'm missing something here.
Am I following the right pattern to accomplish this search?
Should I define an helper method in my controller to generate search urls?
Is it correct that line I have in my _step.rb file?
I don't want urls to be like this: customers/find?name=test
but: customers/find/test
I just sorted it out, I slightly modified my match expression and added the :as parameter
and this gave me the possibility to call find_path() helper method
match 'customers/find/:name' => 'customers#find', :as => :find
Is this correct?
Using :as should indeed create a route helper for you. If you want to get a list of your matched routes, to which controller/action they route, and the name of the route helper, use rake routes in console.

Ruby on rails paths and routes

I'm trying to get the hang of basic Rails routing.
I have a model called page which I generated with a scaffold.
I have added a method called addchild which I would like to access through
'pages/addchild/:id'
So far so good. However, I want to set up a link to this method like so:
<%= link_to 'Add child page', addchild_page_path(page) %>
Passing the ID of the current page as a parameter.
When I load my index view (where the link is), I get the following message:
undefined local variable or method `addchild_page_path' for #<ActionView::Base:0xb67797d0>
Have I misunderstood how the path/link_to method works?
My routes file looks like this:
map.resources :pages
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
Any advice would be greatly appreciated.
Thanks.
You need to add a route to it to be able to use the named path methods.
Since you mentioned you used scaffolding, you probably have the route setup as a resource, so all that you need to do is add the method:
map.resources :pages, :member => {:addchild => :get}
Would give you an addchild_pages_path (and the actual created path would look like /pages/:id/addchild
You then use it like this: addchild_pages_path page, don't call the id method directly since it is not resourceful (you won't use the to_param in the page class, which you might want to do later).
If you really want the url to show up as /pages/addchild/:id (which I don't recommend) you can add
map.addchild_page "/pages/addchild/:id", :controller => :pages, :method => :addchild
before the map.resources :pages row in your routes.rb, and then use the path method as above.

Resources