Rails multiple routes, same `as` - ruby-on-rails

I have the following routes:
authenticated :user do
scope module: 'admin', path: ':publisher_id' do
get 'settings/general', to: 'publishers#index', as: 'publisher_settings'
post 'settings/general', to: 'publishers#create'
put 'settings/general', to: 'publishers#update'
end
end
However the first as: can only be used once. How can I make this apply to all these routes? I want all of them to work for the publisher_settings_path

You can also pass the as option to namespaces and scopes in Rails Routes.
# prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
scope as: "sekret" do
resources :posts
end
Source: https://api.rubyonrails.org/v5.1/classes/ActionDispatch/Routing/Mapper/Scoping.html
This should also work though i think
Rails.application.routes.draw do
resources :publishers, only: [:create, :update, :index], path: 'settings/general', as: 'publisher_settings'
end
Get's me
publisher_settings GET /settings/general(.:format) publishers#index
POST /settings/general(.:format) publishers#create
publisher_setting PATCH /settings/general/:id(.:format) publishers#update
PUT /settings/general/:id(.:format) publishers#update

publisher_settings_path already returns the path of of the three routes, e.g. /admin/settings/general. So you don't need to set as: multiple times.
And actually setting the same as: multiple times for multiple routes would not make sense, it has to return one value.

Related

How to remove resource name from route helper?

I have a route:
resources :promo_pages, path: 'promo' do
get :promo_rubizza, on: :collection, path: 'rubizza', as: :rubizza
end
This route is created - rubizza_promo_pages_path
But I'd like to have - rubizza_path.
How to implement it?
I wanted to implement this as resources :promo_pages, path: 'promo', as: '', but it created rubizza__index_path
UPD: output rails routes
rubizza_promo_pages GET /promo/rubizza(.:format) promo_pages#promo_rubizza
In routes, please define the following route (put it on the same level as resources, without nesting):
get 'promo/rubizza', to: 'promo_pages#promo_rubizza', as: 'rubizza'
Then, you should be able to use rubizza_path and rubizza_url.
what you can do is define this path in your application controller:
class ApplicationController < ActionController::Base
...
def rubizza_path
rubizza_promo_pages_path
end
helper_method :rubizza_path
end
in your routes.rb:
resources :promo_pages, path: 'promo' do
get :promo_rubizza, on: :collection, path: 'rubizza', as: :rubizza
end
That way, you can still use rubizza_path in your views, helpers, controllers, etc. but it uses the full nested route instead.
Customising the routes names details are available here.
What about defining the path based on controller and action?
get 'promo_pages/promo_rubizza', to: 'promo_pages#promo_rubizza', as: :rubizza
it will return:
Prefix Verb URI Pattern Controller#Action
rubizza GET /promo_pages/promo_rubizza(.:format) promo_pages#promo_rubizza

configuring routes for collections in rails

I have a rails application that needs to search two different collections independently, but both are indexed in a single solr instance. However, when i try to search in one collection, when i get to the item i want displayed, it reroutes to the same id within the other collection. How should i adjust my routes.rb to remedy this?
Here is the code:
Rails.application.routes.draw do
get 'biofile/search'
get 'masterfile/search'
mount Blacklight::Engine => '/'
Blacklight::Marc.add_routes(self)
root to: "catalog#index"
concern :searchable, Blacklight::Routes::Searchable.new
resource :catalog, only: [:index], as: 'catalog', path: '/', controller: 'catalog' do
concerns :searchable
end
resource :masterfile, only: [:search], as: 'masterfile', path: '/masterfile', controller: 'masterfile' do
concerns :searchable
end
resource :biofile, only: [:search], as: 'biofile', path: '/biofile', controller: 'biofile' do
concerns :searchable
end
devise_for :users
concern :exportable, Blacklight::Routes::Exportable.new
resources :solr_documents, only: [:show], path: '/catalog', controller: 'catalog' do
concerns :exportable
end
resources :solr_documents, only: [:show], path: 'masterfile', controller: 'masterfile' do
concerns :exportable
end
resources :solr_documents, only: [:show], path: 'biofile', controller: 'biofile' do
concerns :exportable
end
resources :bookmarks do
concerns :exportable
collection do
delete 'clear'
end
end
get '/catalog/masterfile/', to: 'masterfile#search', as: 'masterfile'
get '/catalog/biofile/', to: 'biofile#search', as: 'biofile'
get '*path' => redirect('/')
end
are you asking about nested routes? you want the path to look like model1_model2_path? the below example will give you group_memberships_path to use in your view and the url would have the id of the group and the id of the membership like .../groups/22/membership/13/edit
use rails routes in rails 5.x or rake routes in rails 4 to see the list of your new routes and you can see the urls will take 2 id's that can be passed to your application.
# nested routes for groups
resources :groups do
resources :memberships
end
I think you'll need to override this method https://github.com/projectblacklight/blacklight/blob/9f676994f437f7664cfc2b5c4dffe4382a6d14d3/lib/blacklight/search_state.rb#L48 either by configuration or monkeypatch to behave differently based on some info in solr document

How to define a Rails route on resource member and have it appear at the end of the route name?

I have a route in my Rails application that looks like this:
resources :products
get :specs, on: :member
end
This results in the route helper: specs_product_path instead of product_specs_path. How can I define the route so that the "specs action" is added to the end of the helper method instead of the beginning?
You can always declare a sub-resource which follows this convention:
resources :products do
resources :specs, only: [ :index ]
end
This will require creating another controller, though, with an index action.
You should also be able to override the name with the as: option:
resources :products do
get :specs, on: :member, as: :product_specs
end
Generally it's a good idea to adhere to convention as every exception can lead to confusion or conflict down the road.

Rails nesting scope block in resources

I'm trying to create a path like product/:id/monthly/revenue/ and product/:id/monthly/items_sold and the equivalent named routes product_monthly_revenue and product_monthly_items_sold, and these routes would simply show the charts. I tried
resources :products do
scope 'monthly' do
match 'revenue', to: "charts#monthly_revenue", via: 'get'
match 'items_sold', to: "charts#monthly_items_sold", via: 'get'
end
end
But this gives me the routes:
product_revenue GET /monthly/products/:product_id/revenue(.:format) charts#monthly_revenue
product_items_sold GET /monthly/products/:product_id/items_sold(.:format) charts#monthly_items_sold
where monthly gets appended in front instead, and the route naming is off. I know I could just do:
resources :products do
match 'monthly/revenue', to: "charts#monthly_revenue", via: 'get', as: :monthly_revenue
match 'monthly/items_sold', to: "charts#monthly_items_sold", via: 'get', as: :monthly_items_sold
end
but that isn't DRY, and it gets crazy when I try to add more categories like yearly. Using a namespace would force me to create a new controller for each namespace, when I want to consolidate all the charts into a single controller.
So I guess the summarised question would be: is it possible to namespace routes without namspacing controllers? Or is it possible to consolidate the creation of categories of named routes?
Edit: Using
resources :products do
scope "monthly", as: :monthly, path: "monthly" do
match 'revenue', to: "charts#monthly_revenue", via: 'get'
match 'items_sold', to: "charts#monthly_items_sold", via: 'get'
end
end
would give me the routes
monthly_product_revenue GET /monthly/products/:product_id/revenue(.:format) charts#monthly_revenue
monthly_product_items_sold GET /monthly/products/:product_id/items_sold(.:format) charts#monthly_items_sold
which similar to the first block, is unexpected because I expect that if a scope is nested in a resources block, only the routes in the scope block would affected by the the scope, not the resources block.
Edit 2: Forgot to include this information earlier, but I'm on Rails 4.0.0, with Ruby 2.0.0-p247
The real solution is to use nested:
resources :products do
nested do
scope 'monthly', as: :monthly do
get 'revenue', to: 'charts#monthly_revenue'
get 'items_sold', to: 'charts#monthly_items_sold'
end
end
end
Ref: https://github.com/rails/rails/issues/12626
Here's how I might approach:
periods = %w(monthly yearly)
period_sections = %w(revenue items_sold)
resources :products do
periods.each do |period|
period_sections.each do |section|
get "#{period}/#{section}", to: "charts##{period}_#{section}", as: "#{period}_#{section}"
end
end
end
It is also possible to use named routes and pass the values to your controller method via params (be sure to properly validate before using):
resources :products do
get ":period/:section", to: "charts#generate_report", as: :report
end
# report_path(period: 'monthly', section: 'revenue')

How do I rename a resources routes?

How do I rename some of these routes...for example, below i want to use signup_path in my controllers instead of signup_sessions_path...
resources :sessions, only: [] do
collection do
post :signup, :as => :signup
post :login
delete :logout
end
end
Try not to nest the routes under resources :sessions but rather use the to: option like so:
post :signup, to: 'sessions#signup', as: :signup, on: :collection
Not too sure about your collection there but I'm sure you get the gist of it
Update
According to your comment, as of today, I don't know of any way to remove the nested route resource name from the path name of a nested resource route. In other words, whatever is nested is purposely to use the scope of the resource and therefore there are no options to revert that behaviour other than taking it out of the resource's block.

Resources