Rails 3 add new routes to resources - ruby-on-rails

I have the following problem:
I created one entity "Film" with the command "scaffold" and automatically added in my routes file "resources: films", and then I try to added an autocomplete via ajax, but always the calling ajax calls the "show" action instead of call the route that I added "autocomplete_term"
My routes files (routes.rb)
resources :films
I tried the following possibilities (routes.rb)
match 'films/autocomplete_term' => "films#index", :via=>:get
match "films/autocomplete_term/:term" => "films#autocomplete_term", :controller=>"films", :action=>"autocomplete_term", :as => :films_autocomplete, :via => :get
resources :films do
collection do
get 'autocomplete_term'
end
end
The route
** localhost.com:3000/films/autocomplete_term?term=a**
The ERROR
Couldn't find Film with id=autocomplete_term
app/controllers/films_controller.rb:28:in `show'
When I run the command rake routes
GET /films/autocomplete_term/:term(.:format) films#autocomplete_term
films_autocomplete
GET /films/autocomplete_term/:term(.:format) films#autocomplete_term
autocomplete_term_films
GET /films/autocomplete_term(.:format) films#autocomplete_term
Sorry for my English
And thanks in advance

The url to access this route
GET /films/autocomplete_term/:term
should be
localhost.com:3000/films/autocomplete_term/a
if you do localhost.com:3000/films/autocomplete_term?term=a it will think it is the show action, it will ignore the ?term=a
GET /films/:id

Thanks to Anezio, solved the problem, basicament had two things wrong:
1 - The route
match "films / autocomplete_term /: term"
2: The order in my routes.rb file (Rails routes are matched in the order they are specified)
resources: films
match 'films / autocomplete_term /: term' => "films # autocomplete_term"
The Final Solution: (routes.rb)
match 'films / autocomplete_term' => "films # autocomplete_term"
resources: films

Related

Group routes for paginated model in rails

Can I group 3 routes into 1?
I have this in routes.rb:
# pagination links for resources
get '/countries/page/:page', :to => 'countries#index'
get '/cities/page/:page', :to => 'cities#index'
get '/spots/page/:page', :to => 'spots#index'
If you are looking for a one liner to DRY your thing up, you can always write ruby code directly in your routes.rb file like so:
%w(countries cities spots).each{|v| get "/#{v}/page/:page", to: "#{v}#index" }

Is it possible to have same routes with different show action in rails?

I am trying to reach the following url in my rails app:
example.com/user12 # It should show user#show
exmple.com/wordpress # It should show category#show
My solution: (it does not work)
In the routes.rb I have added :path => '' to both categories and users in order to remove the controllers' name from the url.
resources :categories, :path => ''
resources :users, :path => ''
When I run rake routes, I have the following urls"
category GET /:id(.:format) category#show
account GET /:id(.:format) accounts#show
So I assumed that It should be working correctly, but surely not. It only works for category names and for usernames it shows ActiveRecord::RecordNotFound.
I know, my solution is wrong because I am confusing rails route system and because the resources :categories has more priority over resources :users, the category show page works fine.
So Is there any solution to solve an issue like this?
I have finally found the solution with constraints option. This option accepts regular expressions.
resources :categories, :path => '', constraints: { id: /wordpress|php/ }
Every category should be added manually in this way OR (I am not sure) maybe there is a way to list all categories from database automatically.
One way of doing that is to override the default rails routes, to do that remove the resources
I tested and this works
SampleRails4::Application.routes.draw do
get '/user12', to: 'users#show' #=> users/show
get '/wordpress', to: 'category#show' #=> assuming u have a controller and action
end
however then you have to update the rest of your code, Ex: users/show might be expecting the user id as a param read more about rails routing

Route override doubles records

I'd like to override a default path of an Spree/Rails extension.
The extension spree_contact_us defines default route in it's config/routes.rb this way:
Spree::Core::Engine.routes.draw do
resources :contacts,
:controller => 'contact_us/contacts',
:only => [:new, :create]
match 'contact-us' => 'contact_us/contacts#new', :as => :contact_us
end
In the routes table there is just one record for route named contact-us:
contact_us /contact-us(.:format) spree/contact_us/contacts#new
If I pass following override in main application's config/routes.rb to routes.prepend method
Spree::Core::Engine.routes.prepend do
match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us
end
rake routes displays routes to a new named path twice, when passed to routes.append even three times:
contact_us /napiste-nam(.:format) spree/contact_us/contacts#new
contact_us /napiste-nam(.:format) spree/contact_us/contacts#new
Can anybody explain this behaviour ?
The problem here is that you will be creating an ambiguous named route :contact_us which when referenced by contact_us_path will return the path for the last entry in routes because you are redefining it.
The duplication does seem strange but I have not looked at how spree handles these things.
In order to avoid this you could rename the secondary route such as
Spree::Core::Engine.routes.append do
match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us_czech
end
This should create 2 routes in which you could use contact_us_path and contact_us_czech_path which will both lead to the same place. then create a method to determine which to use.
Or just add the new route directly into the spree routing tables as (PROBABLY NOT VALID DUE TO CALL TO routes_reloader in Spree Core.
match 'napiste-nam' => 'contact_us/contacts#new', :as => :contact_us
match 'contact_us' => 'contact_us/contacts#new', :as => :contact_us
Just remember that this means that contact_us_path with always reference the second route.
Edit
It seems Spree builds the default routes and then reloads them after initializing as is stated in the code
# We need to reload the routes here due to how Spree sets them up.
# The different facets of Spree (backend, frontend, etc.) append/prepend
# routes to Core *after* Core has been loaded.
#
# So we wait until after initialization is complete to do one final reload.
# This then makes the appended/prepended routes available to the application.
config.after_initialize do
Rails.application.routes_reloader.reload!
end
I believe this is causing the named route :contact_us to be routed to it's defined route meaning that you defined it as contact_us and then redefined it as napiste-nam and since a variable can have only 1 value it held on to the second one on reload!. Due to this fact I am not sure you can do this directly through Spree.
Using
Spree::Core::Engine.routes.draw
instead of
Spree::Core::Engine.routes.prepend
solved the routes duplication problem for me.

Routing error for GET] "/firstapp"

I was trying to write my first program after installation, but I got an error like below:
Routing Error
No route matches [GET] "/firstapp"
I've tried to change my config/routes.rb file but nothing changed. This is my config/routes.rb
Firstapp::Application.routes.draw do
resources :apptables
# The priority is based upon order of creation:
# first created -> highest priority.
# continues with default `config/routes.rb` explanations...
end
How can I configure the config/routes.rb to make it run properly?
Just saying resources :apptables sets up the standard seven routes:
GET /apptables
GET /apptables/new
POST /apptables
GET /apptables/:id
GET /apptables/:id/edit
PUT /apptables/:id
DELETE /apptables/:id
There is no /firstapp in that list so that route won't work. If you want a GET on /firstapp to work then you can set up that route manually:
match '/firstapp' => 'firstapp#some_method', :via => :get
That would route GET /firstapp to FirstappController#some_method.

How to remove controller name in REST design in Rails3?

Given a User resource, it goes like this
/user/:shortname
But how can the controller name be removed to get just
/:shortname
How can I declare this in routes.rb while keeping all CRUD functionality instant?
Updated: After reading this I'm moving to Sinatra over Rails to handle this API-like design better.
Define a custom match:
match ':shortname' => 'users#action'
Replace action in users#action with the name of the action that is supposed to receive the request. Just remember to place it in the appropriate order in your routes file. Rails looks at each line of your routes file starting at the top and selects the first matching route. ':shortname' would match any first-level path, including /users! So put it below any routes using a first-level path, which would include all of your resource routes. Here's an example:
resources :users
resources :posts
match '/blog' => 'posts#index'
match ':shortname' => 'users#action'
In routes, you should be able to do something like
resource :users, :path => '/:shortname'
Try that out and rake routes to see if that comes out as expected.

Resources