Params not being passed to method in Rails 3.0.3 - ruby

I have another very puzzling question that has cropped up after my upgrade from Rails 2.3.4 to Rails 3.0.3.
I am calling a 'show' controller method with the following URL:
/verse/10
and I see this in the terminal
Started GET "/verse/10" for 127.0.0.1
at 2011-01-27 16:17:58 -0800
Processing by VersesController#show
as HTML
* Searching for verse with ID:
Rendered verses/show.html.erb within
layouts/application (76.6ms)
Completed 200 OK in 1006ms (Views:
125.4ms | ActiveRecord: 9.8ms)
The verse show method is very simple:
def show
logger.debug("*** Searching for verse with ID: #{params[:id]}")
#vs = Verse.find(params[:id])
end
The route is defined as follows:
match '/verse/:id', :to => 'verses#show', :as => 'verse'
The problem: the parameter, ID, which in this case is '10', is not being passed in to the controller method and so a 404 is being thrown because params[:id] is nil.
The output from "rake routes | grep verse" is as follows:
verse /verse/:id(.:format) {:controller=>"verses", :action=>"show"}
I've spent ages on this but feel as though I'm missing something very obvious.
Here is the full rake routes output:
login /login(.:format) {:controller=>"sessions", :action=>"new"}
logout /logout(.:format) {:controller=>"sessions", :action=>"destroy"}
register /register(.:format) {:controller=>"users", :action=>"create"}
signup /signup(.:format) {:controller=>"users", :action=>"new"}
activate /activate/:activation_code(.:format) {:activation_code=>nil, :controller=>"users", :action=>"activate"}
forgot_password /forgot_password(.:format) {:controller=>"passwords", :action=>"new"}
change_password /change_password/:reset_code(.:format) {:controller=>"passwords", :action=>"reset"}
open_id_complete GET /opensession(.:format) {:controller=>"sessions", :action=>"create"}
open_id_create GET /opencreate(.:format) {:controller=>"users", :action=>"create"}
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"}
passwords GET /passwords(.:format) {:action=>"index", :controller=>"passwords"}
POST /passwords(.:format) {:action=>"create", :controller=>"passwords"}
new_password GET /passwords/new(.:format) {:action=>"new", :controller=>"passwords"}
edit_password GET /passwords/:id/edit(.:format) {:action=>"edit", :controller=>"passwords"}
password GET /passwords/:id(.:format) {:action=>"show", :controller=>"passwords"}
PUT /passwords/:id(.:format) {:action=>"update", :controller=>"passwords"}
DELETE /passwords/:id(.:format) {:action=>"destroy", :controller=>"passwords"}
session POST /session(.:format) {:action=>"create", :controller=>"sessions"}
new_session GET /session/new(.:format) {:action=>"new", :controller=>"sessions"}
edit_session GET /session/edit(.:format) {:action=>"edit", :controller=>"sessions"}
GET /session(.:format) {:action=>"show", :controller=>"sessions"}
PUT /session(.:format) {:action=>"update", :controller=>"sessions"}
DELETE /session(.:format) {:action=>"destroy", :controller=>"sessions"}
quests GET /quests(.:format) {:action=>"index", :controller=>"quests"}
POST /quests(.:format) {:action=>"create", :controller=>"quests"}
new_quest GET /quests/new(.:format) {:action=>"new", :controller=>"quests"}
edit_quest GET /quests/:id/edit(.:format) {:action=>"edit", :controller=>"quests"}
quest GET /quests/:id(.:format) {:action=>"show", :controller=>"quests"}
PUT /quests/:id(.:format) {:action=>"update", :controller=>"quests"}
DELETE /quests/:id(.:format) {:action=>"destroy", :controller=>"quests"}
index /home(.:format) {:controller=>"verses", :action=>"index"}
starter_pack /starter_pack(.:format) {:controller=>"verses", :action=>"starter_pack"}
*verse /verse/:id(.:format) {:controller=>"verses", :action=>"show"}*
tag_cloud /tag_cloud(.:format) {:controller=>"verses", :action=>"tag_cloud"}
show_user_info /show_user_info(.:format) {:controller=>"admin", :action=>"show_user_info"}
show_tags /show_tags(.:format) {:controller=>"admin", :action=>"show_tags"}
contact /contact(.:format) {:controller=>"info", :action=>"contact"}
faq /faq(.:format) {:controller=>"info", :action=>"faq"}
tutorial /tutorial(.:format) {:controller=>"info", :action=>"tutorial"}
volunteer /volunteer(.:format) {:controller=>"info", :action=>"volunteer"}
leaderboard /leaderboard(.:format) {:controller=>"info", :action=>"leaderboard"}
stateboard /stateboard(.:format) {:controller=>"info", :action=>"stateboard"}
countryboard /countryboard(.:format) {:controller=>"info", :action=>"countryboard"}
referralboard /referralboard(.:format) {:controller=>"info", :action=>"referralboard"}
news /news(.:format) {:controller=>"info", :action=>"news"}
update_profile /update_profile(.:format) {:controller=>"profile", :action=>"update_profile"}
referrals /referrals/:id(.:format) {:controller=>"profile", :action=>"referrals"}
unsubscribe /unsubscribe/*email(.:format) {:controller=>"profile", :action=>"unsubscribe"}
edit_tag /edit_tag/:id(.:format) {:controller=>"tag", :action=>"edit_tag"}
tweets /tweets(.:format) {:controller=>"tweets", :action=>"index"}
load_progress /load_progress/:user(.:format) {:controller=>"chart", :action=>"load_progress"}
root /(.:format) {:controller=>"sessions", :action=>"new"}
home /home(.:format) {:controller=>"sessions", :action=>"new"}
/:controller(/:action(/:id))(.:format)

If you have the open_id_authentication plugin installed, that is likely interfering with your routes.

Related

Rails test controller

Trying to test my controller
static_pages_controller_spec.rb
require 'rails_helper'
RSpec.describe StatigPagesController, type: :controller do
it 'return home view' do
get '/'
expect(response).to render_template :home
end
it 'return about view' do
get :about
expect(response).to render_template :about
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'static_pages#home'
get '/about', to: 'static_pages#about'
end
and i get errors
1) StatigPagesController return home view
Failure/Error: get '/'
ActionController::UrlGenerationError:
No route matches {:action=>"/", :controller=>"statig_pages"}
2) StatigPagesController return about view
Failure/Error: get :about
ActionController::UrlGenerationError:
No route matches {:action=>"about", :controller=>"statig_pages"}
I wrote routes, What i'm do wrong?
You have a typo in your static_pages_controller_spec.rb
RSpec.describe StatigPagesController
Try:
RSpec.describe StaticPagesController

401 unauthorized from Twitter API with oauth gem in Ruby

This is my first experience working with Twitter API's.
I am using the following tools:
ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
gem 'oauth'
oauth (0.5.1)
oauth2 (1.1.0)
omniauth-oauth2 (1.4.0)
I obtained a key and secret from Twitter.
I copied and pasted from the example on Twitter for Ruby.
=begin
code taken directly from the example at
https://dev.twitter.com/oauth/overview/single-user
=end
require 'oauth'
consumer_key, \
consumer_secret = [
'CONSUMER_KEY',
'CONSUMER_SECRET'
].map { |key| ENV[key] }
raise "Some key undefined." unless [consumer_key, consumer_secret].all?
# Exchange your oauth_token and oauth_token_secret for an AccessToken instance.
def prepare_access_token(oauth_token, oauth_token_secret)
consumer = OAuth::Consumer.new("APIKey", "APISecret", { :site => "https://api.twitter.com", :scheme => :header })
# now create the access token object from passed values
token_hash = { :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret }
access_token = OAuth::AccessToken.from_hash(consumer, token_hash )
return access_token
end
# Exchange our oauth_token and oauth_token secret for the AccessToken instance.
access_token = prepare_access_token(consumer_key, consumer_secret)
p access_token
# use the access token as an agent to get the home timeline
response = access_token.request(:get, "https://api.twitter.com/1.1/statuses/home_timeline.json")
p response
=begin
|| #<OAuth::AccessToken:0x000000021ed938
#token="redacted", #secret="redacted",
#consumer=#<OAuth::Consumer:0x000000021edb68
#key="APIKey",
#secret="APISecret", #options={:signature_method=>"HMAC-SHA1",
:request_token_path=>"/oauth/request_token",
:authorize_path=>"/oauth/authorize",
:access_token_path=>"/oauth/access_token",
:proxy=>nil, :scheme=>:header,
:http_method=>:post, :oauth_version=>"1.0",
:site=>"https://api.twitter.com"}>,
#params={:oauth_token=>"redacted", :oauth_token_secret=>"redacted"}>
|| #<Net::HTTPUnauthorized 401 Authorization Required readbody=true>
=end
What I tried:
Getting a new key and secret.
Result:
Net::HTTPUnauthorized 401 Authorization Required readbody=true
Synchronized my server's time because many Stack Overflow posts mentioned that a 401 is returned if the server time varies beyond a certain point. I installed ntp.
suggestions from this list
set the Callback URL in Twitter settings: http://127.0.0.1:3000/auth/twitter/callback
API Console Tool on Twitter. After authenticating with my Twitter account https://api.twitter.com/1.1/statuses/home_timeline.json returns
HTTP/1.1 200 OK
along with expected data.
checked to see if Twitter API operating normally
Suggestions of where to go from here appreciated.
UPDATE OAuth Tool on Twitter Developer returns the expected result with a curl execution:
curl --get 'https://api.twitter.com/1.1/statuses/home_timeline.json' --header 'Authorization: OAuth oauth_consumer_key="redacted", oauth_nonce="redacted", oauth_signature="redacted", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1463742270", oauth_token="redacted", oauth_version="1.0"' --verbose
Expected data is returned.
[{"created_at":"Fri May 20 11:05:21 +0000
2016","id":733614584754515968,"id_str":
"733614584754515968","text":"Three Skills Every New Programmer Should
Learn https://t. co/1p9AxO5JPg via
#sitepointdotcom","truncated":false,"entities":{"hashtags":[],"symbols"
(truncated)…
On this line, you should replace "APIKey" and "APISecret" with what you pulled from the CONSUMER_* environment variables.
consumer = OAuth::Consumer.new("APIKey", "APISecret", { :site => "https://api.twitter.com", :scheme => :header })
The example code from Twitter works fine for me. The wrong consumer keys will give you 401 for sure.

Route not found when using Devise's devise_scope

I am using devise for authentication in my app. My routes file look like this:
devise_scope :user do
get "/password_reset" => "devise/passwords#new", :as => "new_user_password"
post "/password_reset/complete" => "devise/passwords#create", :as => "user_password"
get "/password_renew" => "devise/passwords#edit", :as => "edit_user_password"
put "/password_renew/complete" => "devise/passwords#update", :as => "password"
end
The full routes.rb file: http://hastebin.com/vofaluhera.coffee
running rake routes show that these route work well:
new_user_password GET /password_reset(.:format) devise/passwords#new
user_password POST /password_reset/complete(.:format) devise/passwords#create
edit_user_password GET /password_renew(.:format) devise/passwords#edit
password PUT /password_renew/complete(.:format) devise/passwords#update
However when I visit route /password_reset it rases this error:
Could not find devise mapping for path "/password_reset"
Also when I switch to devise_for it work fine but with a deprecation warning and it adds more unwanted routes. So basically, I want to stick with devise_scope
Please help me fix this errors.
Edit:
It turns out that I need to add before using devise_scope
devise_for :users, :skip => [:passwords]

How can we test /user/show?id=xx with rspec?

The route in my system is:
user_show GET /user/show(.:format) user#show.
The controller code is:
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user}
end
end
_spec.rb
describe 'GET #show' do
it 'should return success' do
get :show, id:#user.id
expect(response).to be_success
end
end
result is:
Failure/Error: expect(response).to be_success
expected success? to return true, got false
In the browser, when I type xxx/user/show, it get error.
ActiveRecord::RecordNotFound in UserController#show
But if I type xxx/user/show?id=31, it shows user with id=31!!
Thanks for #Alex Wayne, I add more information here: I check the routes.rb file:
get "user/show"
get "user/index"
get "user/delete"
get "user/edit"
post "user/update"
resource :users, :path => :user, :as => :user
I personal think my teammate should not write down "get user/show, get user/index...." based on Rails Routing. But I can't change their code. So,
anyone know how to test user/show?id=xxx ? Many thanks~!!!!

Rspec request spec looking for singular named controller

I have the following routes defined and the following UsersController defined and when I attempt to run spec test that attempts before { visit signup_path }, I get the following error:
ERROR
Failure/Error: before { visit signup_path}
ActionController::RoutingError:
uninitialized constant UserController
# ./spec/requests/user_pages_spec.rb:7:in `block (3 levels) in <top (required)>'
resources :users
routes.rb
resources :users
match '/signup', to: 'users#new'
match '/help', to: 'static_pages#help'
root :to => 'static_pages#help'
users_controller.rb
class UsersController < ApplicationController
def new
end
def show
#user = User.find(params[:id])
end
end
updated
**user_pages_spec.rb**
describe "UserPages" do
subject { page }
describe "Signup Page" do
before { visit signup_path}
it "Should have header Sign-up" do
should have_selector("h1", text: "Sign-up")
should have_selector("title", text: "Sign-up")
end
end
describe "profile page" do
let(:user) {FactoryGirl.create(:user)}
before { visit user_path(user) }
it { should have_selector("title", text: "#{user.name} Profile")}
it { should have_selector("h1", text: user.name)}
end
end
Here is my 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
signup /signup(.:format) users#new
help /help(.:format) static_pages#help
root / static_pages#help
I can go to www.blah.com/signup without an issue. But the spec is looking for a singular UserController. I can also substitute "signup_path" for "/users/new" and the test will pass.
Also, wanted to add that originally I created the controller (only) using the rails generator using the singular version. But I backed it out after I discovered that by using the rails destroy controller script. Then issued the correct rails generator for the plural version. Like I said, its like the tests are screwed up, but the actual app.

Resources