How do I create custom routes in Ruby on Rails - 4.2 - ruby-on-rails

Right now I have the route as below;
resources :invoices do
collection do
match 'search' => 'invoices#search', via: [:get, :post], as: :search
end
end
But I would like to get 'deliveries#search' instead of 'invoices#search'.
I successfully customized for the below routes;
get 'deliveries', to: 'invoices#index', as: :deliveries
get 'deliveries/new', to: 'invoices#new', as: :delivery
get 'deliveries/:id/edit', to: 'invoices#edit', :as => :del
I have tried but unable to customized for the 'deliveries#search'.
Any suggestions are most welcome.
Thank you in advance.

resources :invoices, path: 'deliveries' do
collection do
match 'search' => 'invoices#search', via: [:get, :post], as: :search
end
end
it will generate route with prefix deliveries like /deliveries/your_action

Change your routes as follows
resources :deliveries, controller: 'invoices', only: [:index, :new, :edit]
resources :deliveries, only: [] do
collection do
get :search
post :search
end
end
This will generate following routes for you:
deliveries GET /deliveries(.:format) invoices#index
new_delivery GET /deliveries/new(.:format) invoices#new
edit_delivery GET /deliveries/:id/edit(.:format) invoices#edit
search_deliveries GET /deliveries/search(.:format) deliveries#search
POST /deliveries/search(.:format) deliveries#search
EDIT
According to your comment I think you just need to use different controller
Try this
resources :deliveries, controller: 'invoices', only: [:index, :new, :edit] do
collection do
get :search
post :search
end
end
This will generate following routes:
search_deliveries GET /deliveries/search(.:format) invoices#search
POST /deliveries/search(.:format) invoices#search
deliveries GET /deliveries(.:format) invoices#index
new_delivery GET /deliveries/new(.:format) invoices#new
edit_delivery GET /deliveries/:id/edit(.:format) invoices#edit

Related

One of my Rails routes requesting favicon.ico

I've just added resources: :favorites, nested inside resources: :deals, to my Rails app. All of a sudden, visiting the deals/deal_slug/favorites/new, after it renders, fires off a GET request to deals/favicon.ico which of course activates the show route, which fails to find anything with the slug of favicon.ico.
It appears to ONLY be the favorites/new route that causes this request, and I've tried commenting out all of favoritescontroller#new as well as the new view, with no change.
Commenting out link href="../../favicon.ico" rel="icon" in my layout fixes it of course, but I'd love to keep that in my layout and figure out why the heck this problem JUST started!
My routes file:
Rails.application.routes.draw do
# what are these??
get 'regions/index'
get 'regions/show'
root "deals#index"
resources :deals, param: :slug do
resources :favorites
end
resources :favorites
get 'my-deals', to: 'deals#my_deals', as: :my_deals_path
resources :regions, param: :slug, only: [:index, :show] do
resources :deals, only: [:index, :show], param: :slug
# resources :deals, only: [:index, :show, :edit, :destroy]
end
resource :preferences
ActiveSupport::Inflector.inflections {|inflect| inflect.irregular 'preferences', 'preferences'} # fix route helper paths so that form_for works
get '/preferences/delete_airport/:airport_id', to: 'preferences#destroy', as: 'delete_home_airport'
resources :vacations
get 'pry', to: 'application#pry'
# ------- DEVISE STUFF --------
devise_for :users, controllers: {
omniauth_callbacks: 'users/omniauth_callbacks',
preferences: 'users/preferences',
}
devise_scope :user do
get "/sign_out", to: 'devise/sessions#destroy', as: 'user_sign_out'
get "/sign_in", to: 'users/sessions#new', as: 'user_sign_in'
get "/sign_up", to: 'devise/registrations#new', as: 'user_sign_up'
get "/user/preferences", to: 'users/preferences#index', as: 'user_preferences'
get "/user/preferences/edit", to: 'users/preferences#edit', as: 'edit_user_preferences'
patch "/user/preferences/:id/edit", to: 'users/preferences#update'
end
devise_for :admins, path: 'admin', controllers: { sessions: 'admins/sessions' }
devise_scope :admin do
get "/admin", to: 'admins/sessions#portal', as: 'admin_root'
get "/admin/sign_out", to: 'devise/sessions#destroy', as: 'admin_sign_out'
end
end
FavoritesController:
class FavoritesController < ApplicationController
def new
prefs = current_user.preferences
#favorite = Favorite.new deal: Deal.find_by(slug: params[:deal_slug]), preference_id: prefs.id
end
def create
#favorite = Favorite.create(favorite_params)
redirect_to preferences_path
end
def favorite_params
params.require(:favorite).permit :preference_id, :deal_id, :comment
end
end
The request for the favicon icon is made by the browser, your code does not trigger that request.
The problem is your favicon href, you are making it relative to the current path: "../../favicon.ico" instead of absolute "/favicon.ico". You'll get the same problem if you have other routes with more than 2 levels since the route is relative.
You should add the favicon.icon somewhere on your public folder and point at it with an absolute path instead. If the icon is in /public/favicon.ico then configure the layout's favicon tag with href="/favicon.ico", if you put the icon somewhere else like /public/icons/favicon.ico then change the link tag to href="/icons/favicon.ico".

Rails custom and default routes

I'm trying to define custom routes to my controller and I need to use some of the default routes too. Is there any simple solution?
So far I've something like this
resources :users do
member do
get 'users/:id', to: 'users#show'
delete 'users/:id', to: 'users#destroy'
end
collection do
post 'users', to: 'users#create'
post 'users/login', to: 'users#login'
end
end
resources :users, :only => [:show, :destroy, :create, :login]
I don't need nor want the index route but with this settings it's still trying to route GET users/ to user_controller index method.
I know that there is probably some simple and obvious answer but I'm not able to find it.
Thank's in advance.
You got your routes wrong. The resources :users generates seven default routes which include the index route as well. You need to tweak the code to below
resources :users, :only => [:show, :destroy, :create] do
collection do
post 'login', to: 'users#login'
end
end
Note:
If you noticed, I've removed the custom routes for show,create and delete as they are generated by default.
Your first line defines the route to the index action. Define a resource once only. Read the routing guide.
resources :users, :except => [:index] do
collection do
post 'users/login', to: 'users#login'
end
end
Run rake routes from the command line in your project root folder to see all your route definitions.

How to rename index path in routes file?

How to rename index path only?
routes.rb
resources :tasks, :except => [:create] do
collection do
..............
end
member do
.............
end
end
instead of /tasks in URL I need /trigger or even /tasks/trigger will do, im on rails3.
I tried
1.
collection do
'/', to: 'tasks#trigger'
end
and
2.
resources :tasks, :except => [:create] do
get '/task', to: 'task#trigger', as: task_index
end
both throw up errors.
any ideas?
For URL like '/trigger' add to routes.rb:
get 'trigger' => 'tasks#index'
For URL like '/tasks/trigger' modify routes.rb:
resources :tasks, :except => [:create] do
collection do
get 'trigger' => 'tasks#index'
end
end
If your index method in task's controller named as 'trigger, 'tasks#index' is replaced by 'tasks#trigger'
If you want to make your own index route then you need to do two things
1- you need to disable index path created by resources
2- Define your own path whatever you want.
As per your requirement you want to make index route as '/trigger'.
Following is the solution.
get 'trigger' => 'tasks#index'
resources :tasks, :except => [:create, :index] do
collection do
..............
end
member do
.............
end
end
Just restraint index route from being generated in your resources call:
resources :tasks, :except => [:create, :index]
And then do your own custom route. For '/trigger':
get 'trigger', to: 'task#trigger', as: 'trigger

Ruby on Rails attribute routing using resources

I'm working on a preservation project where I have models for Institutions, Objects, and Files and I'm using resources in my routes file to help manage all of that. The problem I'm having is that resources uses the :id generated by Ruby on Rails for all of its routes and I would like to use a different attribute. This is particularly important for academic preservation and URL consistency. For example, I would like my show URL for an institution to read institutions/:identifier as opposed to institutions/:id, where :identifier is the attribute I have created. The problem is, I haven't been able to find any information on how to do this aside from just matching individual routes to the new ones I want which seems like a cheap hack at best and breaks a lot of my code.
This is my current routes file:
Fluctus::Application.routes.draw do
#match "institutions/", to: 'institutions#index', via: [:get]
#match "institutions/", to: 'institutions#create', via: [:post]
#match "institutions/:identifier", to: 'institutions#show', via: [:get]
#match "institutions/:identifier", to: 'institutions#update', via: [:patch]
#match "institutions/:identifier", to: 'institutions#update', via: [:put]
#match "institutions/:identifier", to: 'institutions#destroy', via: [:delete]
#match "institutions/:identifier/edit", to: 'institutions#edit', via: [:get]
#match "institutions/:identifier/events", to: 'events#index', via: [:get]
#match "institutions/new", to: 'institutions#new', via: [:get]
#
#match "objects/institution_identifier", to: 'intellectual_objects#index', via: [:get], as: "intellectual_objects_path"
#match "objects/institution_identifier", to: 'intellectual_objects#create', via: [:post]
resources :institutions do
resources :intellectual_objects, only: [:index, :create], path: 'objects'
resources :events, only: [:index]
end
resources :intellectual_objects, only: [:show, :edit, :update, :destroy], path: 'objects' do
resources :generic_files, only: :create, path: 'files'
patch "files/:id", to: 'generic_files#update', constraints: {id: /.*/}, trailing_slash: true, format: 'json'
resources :events, only: [:create, :index]
end
devise_for :users
resources :users do
patch 'update_password', on: :collection
get 'edit_password', on: :member
patch 'generate_api_key', on: :member
end
resources :generic_files, only: [:show, :destroy], path: 'files' do
resources :events, only: [:create]
end
Blacklight.add_routes(self)
mount Hydra::RoleManagement::Engine => '/'
authenticated :user do
root to: "institutions#show", as: 'authenticated_root'
# Rails 4 users must specify the 'as' option to give it a unique name
# root :to => "main#dashboard", :as => "authenticated_root"
end
root :to => "catalog#index"
end
You can see where I have attempted to match individual routes without much luck. I've also looked into FriendlyID without any luck so far. If anyone has any ideas it would be greatly appreciated. Thank you!
Unless I'm missing something here, you should just be able to stick the string you want to use into the URL where the id whould be. For example, /objects/show/1 would become /objects/show/some_string. Then in your controller you can find the object using the id parameter:
def show
#object = Object.where(:some_attribute => params[:id]).first
end

Whenever I scope the routes.rb I get an error in my rails app

I am trying to implement internationalization as seen in railscasts, and every time I scope my routes file I get the error
No route matches [GET] "/"
or the error
missing :controller
config/routes.rb:6:in `block (2 levels) in <top (required)>'
config/routes.rb:5:in `block in <top (required)>'
config/routes.rb:1:in `<top (required)>'
Here is my routes.rb file
Jensenlocksmithing::Application.routes.draw do
get "log_out" => "sessions#destroy", as: "log_out"
get "log_in" => "sessions#new", as: "log_in"
scope ":locale" do
get "site/home"
get "site/about_us"
get "site/faq"
get "site/discounts"
get "site/services"
get "site/contact_us"
get "site/admin"
get "site/posts"
root :to => 'site#home'
end
#match '*path', to: redirect("/#{I18n.default_locale}/%{path}")
#match '', to: redirect("/#{I18n.default_locale}")
match "/savesort" => 'site#savesort'
resources :users
resources :abouts
resources :sessions
resources :coupons
resources :monthly_posts
resources :reviews
resources :categories do
collection { post :sort }
resources :children, :controller => :categories, :only => [:index, :new, :create, :new_subcategory]
end
resources :products do
member do
put :move_up
put :move_down
end
end
resources :faqs do
collection { post :sort }
end
end
So, why whenever I add the scope ":locale" do end line do I get these errors? It all works fine without. Let me know if you need to see any more code. Thanks guys
Edit
In my application controller I have the following:
private
def default_url_options(options = {})
{locale: I18n.locale}
end
Does this do the same thing as the passing the hash in the routes?
Edit 2
I changed my route to the following as seen in this gist.
https://gist.github.com/2322844
So why is the :id part being added to the get route? like this one
about_us_site GET /sites/:id/about_us(.:format)
shouldn't it be something like this
about_us_site GET /sites/about_us(.:format)
Also added my entire routes.rb file and the routes it generates for more information.
https://gist.github.com/2322861
Answer for anyone interested:
I changed
get "site/home"
get "site/about_us"
get "site/faq"
get "site/discounts"
get "site/services"
get "site/contact_us"
get "site/admin"
get "site/posts"
root :to => 'site#home'
to
resources :sites, except: [:new, :edit, :index, :show, :update, :destroy, :create] do
collection do
get :home
get :about_us
get :faq
get :discounts
get :services
get :contact_us
get :admin
get :posts
end
end
Passing in a hash should fix your routes:
scope "(:locale)", :defaults => { :locale => "en" } do
resources :sites
end
Also, you may want to consider creating a SitesController and giving it members:
resources :sites do
member do
get :about_us # Points to /sites/about_us
end
end
Rails Guides on Defining Defaults In Routes

Resources