How do you route [OPTIONS] in Rails? - ruby-on-rails-3

I am making a REST service in Rails. Here are my routes.
resources :users
match '/users', :controller => 'users', :action => 'options', :constraints => {:method => 'OPTIONS'}
I am able to [GET] my users. I am trying to update my users and I get an error:
ActionController::RoutingError (No route matches [OPTIONS] "/users/1"):
When I run rake routes here are the routes that I am given:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
/users(.:format) users#options {:method=>"OPTIONS"}
Could someone please show me how to fix my routes so I can make any kind of REST call? Thanks.

match '/users' => "users#options", via: :options
would also be a possible route if placed before the other routes.

If you don't want to create two additional routes for /users and for /users/id you can do this:
match 'users(/:id)' => 'users#options', via: [:options]
In this case, the id become optional, both /users and /users/id will respond to the same route.

The reason that I could not route the request, was that my match did not have the user id in it. I added the line:
match '/users/:id', :controller => 'users', :action => 'options', :constraints => {:method => 'OPTIONS'}
and now I can route all of my GET request.

If you met this problem using javascript's ajax call, you maybe meet the cross-site problem. (e.g. your browser's current url is : http://a.xx.com and the ajax send a request to http://b.xx.com ) , then Rails / other-backend-server will get this kind of OPTIONS request.
To avoid this, besides changing your ruby code, I suggest you do one of these two solutions:
add CORS support using: https://github.com/cyu/rack-cors, lines of code just work.
send all the request to a.xx.com, then change your Nginx's config, redirect these requests to b.xx.com.
By the way, I don't suggest you change your routes.rb file to support OPTIONS request. This will mess your code up.
refer to: AXIOS request method changes to 'OPTIONS' instead of 'GET'

Related

Devise Users customization causes MissingTemplate on Users, index action in root_path on Heroku

(Rails 3.1, Heroku cedar, ruby 1.9.3, macosx, eclipse, git)
My application is deployed on heroku cedar, and the devise sign-in layer worked fine in the last version but the users-path now throws a missing template error. It works fine on my development machine.
The two big changes I made to the latest is -
1) generating the Users model/view/controller from Devise so I could customize.
2) Added a path prefix to the devise user paths (i.e. registration)
As a test on Heroku, change root_path to a different controller/index (i.e. messages_path), which allowed access to the application. Everything worked, except a click to the home link, which tries again to go to the users_path (same missing template error):
<%= link_to image_tag("homeIcon.png"), users_path, :method =>"GET", :id =>"menulink", :title => "Go Home." %>
I am desperate for any insight into this issue because I can't figure out what to do except not use Devise and Users this way on Heroku.
Any and all ideas are greatly appreciated!
Thanks,
Anne
(Note on research: Searched on the error message; similar issues, but nothing about failing to go to root_path of users#index, nothing related to Devise and Users customization causing error message; reviewed questions list proposed by stackoverflow engin)
Login output local development in eclipe:
Started GET "/" for 127.0.0.1
(0.2ms) SHOW search_path
Processing by UsersController#index as HTML
Redirected to [local-machine]/myprefix/users/sign_in
...
Started GET "/" for 127.0.0.1 at 2014-05-17 08:31:13 -0400
Processing by UsersController#index as HTML
User Load (0.3ms) SELECT "users".* FROM "users"
Login output on Heroku.
Users sign-in, but users/index.html page causes “Sorry, but something went wrong” page.
Started GET "/myprefix/users/sign_in" for ...
heroku[router]: at=info method=GET path=/assets/application...dyno=web.1
Rendered devise/sessions/new.html.erb within layouts/application (53.2ms)
Processing by Devise::SessionsController#new as HTML
cache: [GET /myprefix/users/sign_in] miss
…
heroku[router]: at=info method=POST path=/myprefix/users/sign_in
host=myapp.herokuapp.com
…
Started POST "/myprefix/users/sign_in"
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓"...
Redirected to http://myapp.herokuapp.com/
cache: [POST /myprefix/users/sign_in] invalidate, pass
method=GET path=/ host=myapp.herokuapp.com request_id=f...
Processing by UsersController#index as HTML
Completed 500 Internal Server Error in 49ms
Started GET "/" for ...
ActionView::MissingTemplate (Missing template users/index, application/index
with {:handlers=>[:erb, :builder, :coffee], :formats=>[:html], :locale=>[:en, :en]}.
Searched in:
ActionView::MissingTemplate (Missing template users/index, application/index with
{:handlers=>[:erb, :builder, :coffee], :formats=>[:html], :locale=>[:en, :en]}.
Searched in:
* "/app/app/views"
* "/app/vendor/bundle/ruby/1.9.1/gems/devise-2.2.8/app/views"
):
cache: [GET /] miss
(no other output)
File.properties shows location (i.e. eclipse ide)
[path-to-my-rail-app]/app/views/users/index.html.erb
[path-to-my-rail-app]/app/views/layouts/application.html.erb
routes.rb
MyApp::Application.routes.do
devise_for :views
devise_for :admins
devise_for :users, :path_prefix => 'myprefix'
resources :users do
resources :x, only: [:new, :create, :index, :edit,:destroy]
resources :y, only: [:new, :create, :index, :update, :destroy]
resources :z, only: [:new, :create, :index, :edit,:destroy,:update] do
get :q, :on => :member
end
end
rake routes output:
new_user_session GET
/myprefix/users/sign_in(.:format)
{:action=>"new", :controller=>"devise/sessions"}
user_session POST
/myprefix/users/sign_in(.:format)
{:action=>"create", :controller=>"devise/sessions"}
destroy_user_session DELETE
/myprefix/users/sign_out(.:format)
{:action=>"destroy", :controller=>"devise/sessions"}
user_password POST
/myprefix/users/password(.:format)
{:action=>"create", :controller=>"devise/passwords"}
new_user_password GET
/myprefix/users/password/new(.:format)
{:action=>"new", :controller=>"devise/passwords"}
edit_user_password
GET
/myprefix/users/password/edit(.:format)
{:action=>"edit", :controller=>"devise/passwords"}
PUT /myprefix/users/password(.:format)
{:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration
GET /myprefix/users/cancel(.:format)
{:action=>"cancel", :controller=>"devise/registrations"}
user_registration POST /myprefix/users(.:format)
{:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET
/myprefix/users/sign_up(.:format)
{:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET
/myprefix/users/edit(.:format)
{:action=>"edit", :controller=>"devise/registrations"}
PUT /myprefix/users(.:format)
{:action=>"update", :controller=>"devise/registrations"}
DELETE /myprefix/users(.:format)
{:action=>"destroy", :controller=>"devise/registrations"}
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
new_user GET /users/new(.:format)
{:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format)
{:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format)
{:action=>"show", :controller=>"users"}
PUT /users/:id(.:format)
{:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format)
{:action=>"destroy", :controller=>"users"}
root /
{:controller=>"users", :action=>"index"}
gemfile:
source 'http://rubygems.org'
gem 'bundler'
ruby "1.9.2"
gem 'rails', '3.1.3'
gem 'rails_12factor', group: :production
gem 'pg'
gem 'devise'
users_controller.rb:
class UsersController < ApplicationController
def index
#users = User.active_users
end
end
appliction.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
require 'devise'
Apparently your application can't find the users/index.html.erb file.
Can you confirm that the file exists, and that it has been pushed to production too?
Well, it's fixed, but in the weirdest way. Thanks to all the stackexchange posts that gave me the incremental insights, and to Raul who pushed the verification idea.
Here's the gist of it for anyone else stuck in cloud-hell.
1 - views/Users needed to be views/users. somehow my local environment create *U*sers.
The entire /user location seemed to be pushed to heroku, but apparently not.
2 - (after Raul's question, and an hour trying to find the heroku directory structure)
Made a simple typo change to /users/index.html, to see if there was an error when I tried to commit it.
During the commit (eclipse git window), I noticed the filename in the project explorer flicking between 'Users/' and 'users, the entire time.
Once the git commit completed and I did yet another heroku push master, the problem was solved. I now land on /users/index.html
Thanks to everyone for the save, I love this site.
Anne

Devise & MongoMapper & Rails - Cannot see any devise pages (broken routes / actions)

I am getting "too many redirects" when I'm trying to access my /users/sign_up page
Devise + MongoMapper + Rails 3.2.13
rake routes:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
new_user_session GET /users/login(.:format) devise/sessions#new
user_session POST /users/login(.:format) devise/sessions#create
destroy_user_session DELETE /users/logout(.:format) devise/sessions#destroy
user_password POST /users/reset(.:format) devise/passwords#create
new_user_password GET /users/reset/new(.:format) devise/passwords#new
edit_user_password GET /users/reset/edit(.:format) devise/passwords#edit
PUT /users/reset(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / customers#index
customers GET /customers(.:format) customers#index
POST /customers(.:format) customers#create
new_customer GET /customers/new(.:format) customers#new
edit_customer GET /customers/:id/edit(.:format) customers#edit
customer GET /customers/:id(.:format) customers#show
PUT /customers/:id(.:format) customers#update
DELETE /customers/:id(.:format) customers#destroy
Rails server console just spits this out over and over:
Started GET "/users/sign_in" for 127.0.0.1 at 2014-02-24 21:10:01 -0800
Processing by UsersController#show as HTML
Parameters: {"id"=>"sign_in"}
Completed 401 Unauthorized in 0ms
I read on their ReadMe that Devise is supposed to make some helper methods in my controller - I don't see any but the standard 7 from the generator.
It seems like it's trying to login as "sign_in" which I certainly didn't instruct it to do - this is a brand new Rails application basically just with one model - User - and one model - Customer - and absolutely no data or any other files yet. Literally just trying to get this Devise login page to render - or signup page - or any page.
Here is my entire routes.rb file right now:
resources :users
devise_for :users
root :to => "customers#index"
resources :customers
This happens when I have before_filter authenticate_user! in my Users Controller
So when I take that line out - and I just try to hit /users/sign_up - I get the following:
No route matches {:action=>"edit", :controller=>"users", :id=>nil}
It's supposed to redirect here:
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
The controller action is :
def edit
#user = User.find(params[:id])
end
And of course - since there's nothing in my DB at all - #user is nil now - is that the issue?
How do people get Devise started??? I've never once successfully got this stupid thing to work.
You should have the line:
devise_for :users
above the line:
resources :users
That is because you need to set up the Devise resources for a model before anything else.
What you could also do is remap the Devise routes to you own. You'd replace resources :users with a devise_scope block. Here is the Documentation for it.

Rails: how to retain session when redirecting to canonical domain (e.g. company.example.com -> example.com)

Rails 3.2.12, ruby 1.9.3
We allow users to specify the company they are with using a subdomain, like mycompany.example.com, but we redirect to the canonical example.com and need to remember that the user is from mycompany.
We have our environment set up so the config.session_store contains :domain => 'example.com (an alternative that also works is :domain => :all, :tld_length => 2) and this is supposed to work to allow sharing of session information between subdomains. There are a number of great posts, such as this one: Share session (cookies) between subdomains in Rails?
But before the redirect I am sending session.inspect to the log, and it's clearly getting a different session (two separate session ids, etc.). So the most basic issue is that I cannot use the session to remember the mycompany part before I strip it off.
I can work around that, but there are a number of cases where the same user will be from multiple companies (and part of this is our support team who needs to be able to switch companies).
I have tried this on Chrome and Safari on OS X. I am using "pow" so my local development environment has a domain like example.dev which helps rule out several issues (vs. normal localhost:3000 server).
Am I missing something? Is it indeed possible to share a cookie across domains?
UPDATE:
Example code called in a before_filter defined in ApplicationController:
def redirect_to_canonical_if_needed
logger.debug "Starting before_filter. session contains: #{session}"
if request.host != 'example.com'
session[:original_domain] = "Originally came from #{request.host}"
logger.debug "Redirecting, session contains: #{session}"
redirect_to 'http://example.com', :status => :moved_permanently
end
end
Setting added to config/environments/production.rb and removed from config/initializers/session_store.rb
config.session_store = { :key => 'example_session', :secret => "secret", :domain => :all, :tld_length => 2 }
or
config.session_store = { :key => 'example_session', :secret => "secret", :domain => 'example.com' }
And logging result, if I start from a fresh environment where no session exists going to the url a.example.com:
Starting before_filter, session contains: {}
Redirecting, session contains: {"session_id"=>"4de9b56fb540f7295cd3192cef07ba63", "original_domain"=>"a.example.com"}
Filter chain halted as :redirect_to_canonical_if_needed rendered or redirected
Completed 301 Moved Permanently in 2294ms (ActiveRecord: 855.7ms)
Started GET "/" for 123.456.789.123 at 2013-07-12 09:41:12 -0400
Processing by HomeController#index as HTML
Parameters: {}
Starting before_filter, session contains: {}
So the before filter fires on each new request. First request there's no session, hence the "not loaded" message. The test for need to redirect is true. I put something in the session and it gets an id and what I put in it. I do the redirect. New request occurs on the root domain, before filter fires again, and here's the issue: session is not initialized
This should work fine between the two I have setup the following on my dev
Application is at example.dev
I view and set a session variable at a.example.dev then visit b.example.dev and it is set as long as when (as you describe) you set domain to 'example.dev' for the session store
This code in my root controller/action does exactly what your describing
unless request.subdomain.to_s == 'another'
session[:original_domain] = request.subdomain.to_s
redirect_to 'http://another.' + request.domain.to_s
end
And viewing original_domain is available in the session
If you put the example code in I can have a look for any pitfalls

Rails - Devise - Routes issue

I'm trying to get devise set up and running in my app but I've hit the wall with it.
I'm seeing the this error message when i try
Routing Error
No route matches {:controller=>"devise/clubs"}
Now the URL in my browser is
http://localhost:3000/users/sign_up
but I get the above, so I don't know where "devise/clubs" is coming from.
Now my routes file looks like so
Mess::Application.routes.draw do
devise_for :users
resources :news , :clubs
root :to => "clubs#index"
end
When I run rake routes I see
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
news_index GET /news(.:format) news#index
POST /news(.:format) news#create
new_news GET /news/new(.:format) news#new
edit_news GET /news/:id/edit(.:format) news#edit
news GET /news/:id(.:format) news#show
PUT /news/:id(.:format) news#update
DELETE /news/:id(.:format) news#destroy
clubs GET /clubs(.:format) clubs#index
POST /clubs(.:format) clubs#create
new_club GET /clubs/new(.:format) clubs#new
edit_club GET /clubs/:id/edit(.:format) clubs#edit
club GET /clubs/:id(.:format) clubs#show
PUT /clubs/:id(.:format) clubs#update
DELETE /clubs/:id(.:format) clubs#destroy
root / clubs#index
In form for creating the link i have
<%= link_to 'Sign up as User', new_user_registration_path %>
Routes tells me
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
It looks alright from the rake routes dump.
I've tried different variations in my routes.rb but I cant get this to work. I'm using rails 3.2.2 and ruby 1.8.7. Stepping up in the ruby version is not an option. (Host provider uses these two versions)
I checked the docs for devise, maybe I need to step down a version?? This is my first rails app so I'm learning by doing.
In my gem file I have:
gem "devise"
So it is the latest 2.1.2 version!!
Any help, tips are greatly appreciated.
Logs from the console look like so
Started GET "/users/sign_up" for 127.0.0.1 at Sun Sep 02 12:54:01 +0200 2012
Processing by Devise::RegistrationsController#new as HTML
Rendered devise/shared/_links.erb (0.7ms)
Rendered devise/registrations/new.html.erb within layouts/application (4.0ms)
Rendered application/_default_navigation.html.erb (1.4ms)
Completed 500 Internal Server Error in 35ms
ActionController::RoutingError (No route matches {:controller=>"devise/clubs"}):
app/views/application/_default_navigation.html.erb:2:in
_app_views_application__default_navigation_html_erb___767051374_2180756000'
app/views/layouts/application.html.erb:32:in
_app_views_layouts_application_html_erb___31524913_2182039900'
Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.4ms)

Problem with restful route in Rails 3

I have the following in routes.rb:
resource :account, :controller => "accounts"
resources :accounts
this redirect is in a controller:
redirect_to account_url
and when this redirect is called, I get the following error:
Routing Error
No route matches {:action=>"destroy", :controller=>"accounts"}
The following are displayed when running rake routes:
...
...
accounts DELETE /accounts(.:format) {:action=>"destroy", :controller=>"accounts"}
...
...
account DELETE /accounts/:id(.:format) {:action=>"destroy", :controller=>"accounts"}
...
...
So it seems to me that I've got the {:action=>"destroy", :controller=>"accounts"} covered -> according to rake routes anyways. Anyone have an idea as to what I'm doing wrong?
What's that first route's intention? It should be enough with the second one to map HTTP verbs to controller actions automatically.