How to add custom URLs - ruby-on-rails

How to add custom URLs like localhost:3000/one_hour/page/2 instead of localhost:3000/one_hour?page=2
to get '/one_hour', to: 'feed_entries#one_hour'
I use Rails 4, Kaminari and mongoid
routes.rb
Rails.application.routes.draw do
concern :paginatable do
get '(page/:page)', :action => :index, :on => :collection, :as => ''
end
resources :feed_entries, path: 'news', :concerns => :paginatable
get '/one_hour', to: 'feed_entries#one_hour'
end
feed_entries_controller.rb
class FeedEntriesController < ApplicationController
one_hour
#feed_entries = FeedEntry.includes(:source).one_hour.page(params[:page])
end
end

I found a solution:
in routes.rb
get 'one_hour/(page/:page)', controller: 'feed_entries', action: 'one_hour', to: 'feed_entries#one_hour', as: :one_hour

Related

paginate 'nested' rails routes for seo

I need to figure out how to properly use routes to create a url structure like so:
items/page/2
items/expired/page/2
I have items/page/2 working and then I have this which I want to to correct:
items/expired?page=2
I am using Kaminari to provide pretty url structure for rails 4.2 with a concern.
https://github.com/amatsuda/kaminari/#creating-friendly-urls-and-caching
My controller has two actions: index and expired
My views under items are index.html.haml and expired.html.haml
routes.rb
concern :paginatable do
get '(page/:page)', :action => :index, :on => :collection, :as => ''
end
concern :expired_paginatable do
get '(page/:page)', :action => :expired, :on => :collection, :as => ''
end
get 'items/expired', to: "items#expired", :concerns => :expired_paginatable
resources :items, :concerns => :paginatable
my views both have:
= paginate #items
I know I do not need two concerns but thought I would try it.
I ended up changing my resources block to this:
resources :items do
collection do
get 'expired/page/:page', :action => :expired
get :expired
end
concerns :paginatable
end
dropping:
concern :expired_paginatable do
get '(page/:page)', :action => :expired, :on => :collection, :as => ''
end
get 'items/expired', to: "items#expired", :concerns => :expired_paginatable
resources :items, :concerns => :paginatable

Why is Rails generating two routes for the same resource

Given the following routes file:
Rails.application.routes.draw do
root to: 'visitors#index'
devise_for :users
resources :users do
resources :wishlists, :only => [:create] do
post :action => :create, :on => :collection
resources :items, :only => [:create, :update, :remove_item] do
post :action => :create, :on => :collection
put :action => :update
delete :action => :remove_item
end
end
end
end
Rails generates routes including the following routes which conflict:
PUT /wishlists/:wishlist_id/items/:item_id(.:format) items#update
wishlist_item PUT /wishlists/:wishlist_id/items/:id(.:format) items#update
Why does the first of these get generated? I would expect only the second one (which includes the path helper)
I'm using Rails 4.1.4
Because your are declaring 2 times the same route:
the first one in resources :items, :only => [:create, :update, :remove_item] generates this resource: /wishlists/:wishlist_id/items/:id(.:format)
the second in put :action => :update generates this one: /wishlists/:wishlist_id/items/:item_id(.:format)
You should be using only 1 of them (I recommend the first one).
If you want more information on routing, you should definitely go on this page.

Can anyone help me with this code? I need to convert it to rails 4 but I don't know how..(routes.rb file from rails 2 to rails 4)

ActionController::Routing::Routes.draw do
map.resources :users, :sent
map.resources :mailbox, :collection => { :trash => :get }
map.resources :messages, :member => { :reply => :get, :forward => :get, :reply_all => :get, :undelete => :put }
map.resource :session
map.inbox '', :controller => "mailbox", :action => "index"
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
I believe what you're looking for is this:
ActionController::Routing::Routes.draw do
root to: "mailbox#index"
resources :users
resources :sent
resources :mailbox do
collection do
get :trash
end
end
resources :messages do
member do
get :reply
get :forward
put :undelete
end
end
resource :session
end
The two connect routing definitions are no longer used in Rails, as they make all actions of all controllers available as GET requests. For instance, GET /users/1/destroy. If you find routes that that used to work are no longer working, you will need to define new routes in config/routes.rb for them.

Devise routing error: "Unknown action -- The action 'create' could not be found for UsersController"

My devise set up was working fine before, but now, for some reason, whenever I try to sign up a new user, it tries to call users#create instead of registrations#create. I think it must be a problem with my routes.rb file. I recently added a new resource, "preferences", to my application, so the routing might be wonky:
Indexer2::Application.routes.draw do
resources :preferences
get "home/index"
resources :posts
resources :users
devise_for :users, :controllers => {:registrations => 'registrations', :invitations => 'invitations'}, :except => [:show] do
get "/signup" => "devise/registrations#new", :as => 'user_signup'
get '/logout' => 'devise/sessions#destroy', :as => 'user_logout'
get '/login' => "devise/sessions#new", :as => 'user_login'
end
match '/welcome' => 'pages#welcome'
resources :preferences, :except => [:destory, :edit, :create, :new, :index, :show] do
collection do
post "make_feed_preference"
post "change_preference"
end
end
root :to => "home#index"
end
Your UsersController should have create method.
If you don't want to write your own registration logic just do inheritance from Devise::RegistrationsController < DeviseController:
controller UsersController < Devise::RegistrationsController
#....
end
This will include default Devise methods.

Uninitialized Constant Error in Nested Controller

I am getting this error:
Routing Error
uninitialized constant RegistrationsController
This is my log:
Started GET "/registrants/1/registrations/new" for 127.0.0.1 at 2012-07-03 00:55:44 -0500
ActionController::RoutingError (uninitialized constant RegistrationsController):
Rendered /.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.1.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (8.5ms)
This is the part of my routes.rb that is appropriate:
registrant_registrations GET /registrants/:registrant_id/registrations(.:format) {:action=>"index", :controller=>"registrations"}
POST /registrants/:registrant_id/registrations(.:format) {:action=>"create", :controller=>"registrations"}
new_registrant_registration GET /registrants/:registrant_id/registrations/new(.:format) {:action=>"new", :controller=>"registrations"}
edit_registrant_registration GET /registrants/:registrant_id/registrations/:id/edit(.:format) {:action=>"edit", :controller=>"registrations"}
registrant_registration GET /registrants/:registrant_id/registrations/:id(.:format) {:action=>"show", :controller=>"registrations"}
PUT /registrants/:registrant_id/registrations/:id(.:format) {:action=>"update", :controller=>"registrations"}
This is my Registrations Controller, which is at /app/controllers/portal/registrations_controller.rb:
class Portal::RegistrationsController < ApplicationController
def create
#registrant = current_member.registrants.find(params[:registrant])
#registration = #registrant.registrations.build
respond_to do |format|
if #registration.save
format.html { redirect_to root_path, :notice => "Registration successfully created!" }
format.json { head :ok }
else
format.html { redirect_to root_path, :notice => "There was a problem with the registration." }
end
end
end
end
I get this error when I call new_registrant_registration_path(registrant) from a view in Portal#index.
Edit:
For completeness, here is my routes.rb file in its entirety before the solution was found. Radar mentioned the gist I posted, but I figured I would put the code here in case that gist is deleted.
MyApp::Application.routes.draw do
match 'admin' => 'admin/dashboard#index', :as => :admin_root
match 'portal' => 'portal#index', :as => :member_root
namespace 'admin' do
match 'profile' => 'profile#show', :as => :profile
resources :members
resources :admins
resources :packages
resources :products
resources :levels
resources :lessons
resources :registrations
resources :registrants, :controller => 'customers/registrants'
resources :locations
resources :schools
resources :terms
resources :customers
resources :invoices
resources :payments
end
namespace 'member' do
resources :registrations
end
match 'register' => 'member/registrations#new', :as => :signup
match 'login' => 'member_sessions#new', :as => :login
match 'logout' => 'member_sessions#destroy', :as => :logout
match 'admin/login' => 'admin_sessions#new', :as => :admin_login
match 'admin/logout' => 'admin_sessions#destroy', :as => :admin_logout
match 'member/activate/:activation_code' => 'member/activations#create', :as => :member_activation
match 'member/:id/activate/resend' => 'member/activations#resend', :as => :resend_member_activation
match 'member/:id/activate' => 'member/activations#new', :as => :new_member_activation
match 'member/password/reset/begin' => 'member/password_resets#new', :as => :new_member_password_reset, :via => :get
match 'member/password/reset' => 'member/password_resets#create', :as => :member_password_resets, :via => :post
match 'member/password/:token/finish' => 'member/password_resets#edit', :as => :edit_member_password_reset, :via => :get
match 'member/password/reset' => 'member/password_resets#update', :as => :member_password_reset, :via => :put
match 'admin/packages/new/:partial' => 'admin/packages#new'
resources :admins
resources :registrants, :controller => 'portal/registrants' do
resources :registrations
end
resource :admin_session
resource :member_session
root :to => 'portal#index'
end
To make things clear: marcamillion came into #rubyonrails and Freenode and shared his config/routes.rb. That's where I figured out the error that he was making and then figured out the answer.
Two things.
First: Admin root route
Rather than defining the root route for your admin namespace like this:
match 'admin' => 'admin/dashboard#index', :as => :admin_root
Define it inside the namespace :admin call like this:
namespace 'admin' do
root :to => "dashboard#index"
end
This will automatically define it as admin_root_path and admin_root_url, so you won't need to do that, and it will automatically prefix the controller with the admin/ prefix, so you won't need to do that either.
Second: Referencing RegistrantsController
You have this currently in your config/routes.rb:
resources :registrants, :controller => 'portal/registrants' do
resources :registrations
end
What this will do is define resources routes for registrants correctly using the Portal::RegistrantsController, but won't define the nested routes underneath this using Portal::RegistrationsController. What it will do is attempt to use RegistrationsController, which is why you're getting that error.
To fix this, I'd recommend you use the scope method, like this:
scope :module => Portal do
resources :registrants do
resources :registrations
end
end
The scope method, when used in this way, will tell Rails that the controllers for the routes inside the block are under the Portal namespace. This means that it will know that resources :registrants is for Portal::Registrants and that resources :registrations is for Portal::Registrations, thereby fixing the error that you're seeing.
What if you change this line:
class Portal::RegistrationsController < ApplicationController
to:
class RegistrationsController < ApplicationController
?
This is strange. I think, your controller should be located at /app/controllers/registrants/registrations_controller.rb and looks like this:
class Registrants::RegistrationsController < Registrants::ApplicationController
def create
#registration = registrant.registrations.build
...
end
end
class Registrants::ApplicationController < ApplicationController
def registrant
current_member.registrants.find(params[:registrant_id])
end
end
Registrants::ApplicationController (/app/controllers/registrants/application_controller.rb) controller aim is to avoid code duplication.

Resources