I'm trying to set up some semistatic page in a rails 3 app
I've created a Pages controller with some non restful actions
class PagesController < ApplicationController
def home
end
def about
end
def contact
end
def monday
end
def saturday
end
def sunday
end
end
It's showing at /pages/home etc.
Is there a way to re-route the pages so that they show under /home etc.
I've tried
resources :pages, :path => '/' do
#blah
end
but I get an error message telling me that the :action => show is missing.
Is it possible to apply a setting to all non restful actions?
You could add collection routes:
resources :pages do
collection do
get 'home'
get 'about'
get 'contact'
...
end
end
Related
I'm trying to create a thank you page, my route for this works fine since I test it the url and works just fine, however when I try to redirect in the create action I get:
Routing Error
No route matches {:action=>"thank_you", :locale=>:en, :controller=>"appointments"}
Controller
def create
#appointment = Appointment.new(params[:appointment])
if #appointment.save
#send email
AppointmentMailer.appointment_confirmation(#appointment).deliver
AppointmentMailer.new_appointment(#appointment).deliver
redirect_to :action => "thank_you"
else
render :action => 'new', :alert => #appointment.errors.full_messages.split(', ')
end
end
def thank_you
#appointment = Appointment.find(params[:id])
end
Route
resources :appointments, :except => :new do
member do
get :thank_you
end
end
You need to add it as a RESTful action (or assume a default matching route).
Nutshell:
resources :appointments do
member do
get 'thank_you'
end
end
Or:
resources :appointments do
get 'thank_you', :on => :member
end
For getting a new page, you have to do more than just editing the controller.
Edit config/routes.rb and include
match "/appointments/thank_you" => "appointments#thank_you"
You might want to insert render command in the controller, that brings you to a thank you view you have to create...
I'm working with rails 3.2 and Devise (the lastest version)
The main idea if the test some variables of the current logged user after sign in. So, for example, if the user has pending creating an address i want to redirect the new address path. But what i get is a double render error.
Here is the code
class ApplicationController < ActionController::Base
protect_from_forgery
# Devise: Where to redirect users once they have logged in
def after_sign_in_path_for(resource)
if current_user.is? :company_owner
if $redis.hget(USER_COMPANY_KEY, current_user.id).nil?
redirect_to new_owner_company_path and return
else
#addr_pending = $redis.hget(PENDING_ADDRESS_KEY,current_user.id)
unless #addr_pending.nil? || !#addr_pending
redirect_to owner_company_addresses_path and return
end
end
end
root_path
end
end
my routes definition
root :to => "home#index"
devise_for :users, :controllers => {
:omniauth_callbacks => "users/omniauth_callbacks"
}
resources :users, :only => :show
namespace :owner do
resource :company do # single resource /owner/company
get 'thanks'
get 'owner' #TODO: esto hay que sacarlo de aquĆ y forme parte del login
resources :addresses
end
end
So, when i login with a user with a pedding address creation i get
"render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
what is wrong with?
redirect_to owner_company_addresses_path and return
So, i just want to redirect to the new address path. I don't understand why i get the error.
Thanks in advance.
---- edit ----
Seems that only one path must be returned (I thought with redirect_to and return was enough, but it does not)
def after_sign_in_path_for(resource)
#final_url = root_path
if current_user.is? :company_owner
if $redis.hget(USER_COMPANY_KEY, current_user.id).nil?
#final_url = new_owner_company_path
else
#addr_pending = $redis.hget(PENDING_ADDRESS_KEY,current_user.id)
unless #addr_pending.nil? || !#addr_pending
#final_url = owner_company_addresses_path
end
end
end
#final_url
end
You should remove redirect_to method call and return statement. after_sign_in_path_for should return only a path:
E.g:
def after_sign_in_path_for(resource)
new_owner_company_path
end
Well the title Question pretty much sums it up, But I'd like to detail a scenario anyways,
I've created a DemoController, (I have not created a Resource model), and my routes.rb looks like this:
DispatchMe::Application.routes.draw do
root to: "demo#index"
end
From the demo controller I'm dong the following:
class DemoController < ApplicationController
def index
redirect_to :action => 'show'
end
def show
end
end
There is a file in: app/views/demo/show.html.erb of course, And I'd expected that template to be rendered but instead I'm getting the following error:
ActionController::RoutingError (No route matches [GET] "/assets")
and this URL is generated as a result from the redirect:
/assets?action=show&controller=demo
Am I missing something here? I thought rails was supposed to render the action's template for such cases.
Note. I understand that If I create a route like get 'show' => "demo#show" and call redirect_to show_path it'll work just fine, But I need to know if that's mandatory?
Thank you very much!
For the desired behavior, use render instead of redirect_to:
class PagesController < ApplicationController
def index
render :action => "show"
end
def show
end
end
EDIT:
You can use redirect_to on other actions, but from what I can tell, the index action sets the base path. To simplify route definition, use resources :controller_name. You can view the routes generated by resources by typing rake routes in your command line.
Example:
demo_controller.rb
class DemoController < ApplicationController
def index
end
def show
redirect_to :action => 'index'
end
end
routes.rb
DispatchMe::Application.routes.draw do
root to: "demo#index"
resources :demo
end
development.log
Started GET "/demo/show" for 127.0.0.1 at 2012-04-04 14:55:25 -0400
Processing by DemoController#show as HTML
Parameters: {"id"=>"show"}
Redirected to http://dispatch.dev/
Completed 302 Found in 0ms (ActiveRecord: 0.0ms)
New to rails 3
I would like to create a contact form that people fill out, its saved to the db and then a thank you page comes up.
I would like to do this without scaffold so I can learn better, and I figure that by doing it this way it would be easer to setup so that people cannot try and look at other people's entries by modifying the url.
ideally it would keep their state in the session or cookie so that they would end up on the thanks page if they came back.
Have been trying to do this for about 3 days and reading/googling tons, but between the new routes redirect_to controller stuff in rails3 havn't managed to figure it out.
Routes.rb
Contact::Application.routes.draw do
resources :contactees, :only => [:new, :create]
# to make sure crud doesn't have the routest I don't want
get 'contactees/submitted'
root :to => 'contactees#new'
contactees_controller.rb
ContacteesController < ApplicationControler
def share
end
def new
#contactee = Contactee.new
end
def create
#contactee = Contactee.new(params[:contactee])
if #contactee.save
redirect_to submitted_contactee
else
render action: "new"
end
end
end
Views
contactees
_form.html.erb
new.html.erb
submitted.html.erb
Get rid of the submitted route, you don't need it. Perhaps something like this?
def new
render :submitted if session[:contacted]
end
def create
#contactee = Contactee.new(params[:contactee])
if #contactee.save
session[:contacted] = true
render :submitted
else
render action: "new"
end
end
I'm new to Rails, and a bit confused about routes:
I have a Devices controller:
#devices_controllers.rb
class DevicesController < ApplicationController
def index
#devices = Device.all
end
def show
#device = Device.find(params[:id])
end
def new
#device = Device.new
end
def create
#device = Device.new(params[:device])
if #device.save
flash[:notice] = "Successfully created device."
redirect_to #device
else
render :action => 'new'
end
end
def edit
#device = Device.find(params[:id])
end
def update
#device = Device.find(params[:id])
if #device.update_attributes(params[:device])
flash[:notice] = "Successfully updated device."
redirect_to #device
else
render :action => 'edit'
end
end
def destroy
#device = Device.find(params[:id])
#device.destroy
flash[:notice] = "Successfully destroyed device."
redirect_to devices_url
end
def custom_action
"Success"
end
I'd like to access the "custom_action" action via a url like this:
http://foo.bar/devices/custom_action
I've added this line to my routes.rb file:
match 'devices/custom_action' => 'devices#custom_action'
However, when I try the URL in the browser, I get this error:
ActiveRecord::RecordNotFound in DevicesController#show
Couldn't find Device with ID=custom_action
It seems to be going to #show action instead of #custom_action. If a user id is not supplied, and I go to http://foo.bar/devices/custom_action, I'd like it to go #custom_action.
I've read Rails Routing from the Outside, but still can't still seem to figure out the problem.
I think the problem may be because of the order in which you have defined your routes.
I suspect you have resources :devices in your routes.rb. In addition, I suspect you have defined your custom route after this. If you type rake routes into your console/terminal, you will see that there is already a route defined for the following pattern:
GET /devices/:id
This route is a product of resources :devices, which is taking precedence over your custom route. Referring back to the Edge Guides, specifically in 1.1. Connecting URLs to Code, it states that the request will be dispatched to the first matching route. So a simple fix would be to define your custom route before resources :devices.