I'm totally stumped on this error. Would really appreciate some help :).
To reproduce the error, you can pull the program from https://github.com/WaleyChen/twitter_clone. Then run 'bundle exec rspec spec/'.
I have an rspec test for my controller defined as:
require 'spec_helper'
describe FrontpageController do
render_views # render the views inside the controller tests, so not just test the actions
describe "GET 'frontpage'" do
it "should be successful" do
get 'frontpage'
response.should be_success
end
it "should have the right title" do
get 'frontpage'
response.should have_selector("title", :content => "Twitter")
end
end
end
When I run my rspec tests, I get the following error:
Failures:
1) FrontpageController GET 'frontpage' should be successful
Failure/Error: get 'frontpage'
ActionView::Template::Error:
undefined method `full_name' for #<User:0x007fbfce43dce0>
# ./app/views/frontpage/frontpage.html.erb:22:in `block in _app_views_frontpage_frontpage_html_erb___4518234645475110659_70230885952360'
# ./app/views/frontpage/frontpage.html.erb:21:in `_app_views_frontpage_frontpage_html_erb___4518234645475110659_70230885952360'
# ./spec/controllers/frontpage_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
2) FrontpageController GET 'frontpage' should have the right title
Failure/Error: get 'frontpage'
ActionView::Template::Error:
undefined method `full_name' for #<User:0x007fbfcc99a410>
# ./app/views/frontpage/frontpage.html.erb:22:in `block in _app_views_frontpage_frontpage_html_erb___4518234645475110659_70230885952360'
# ./app/views/frontpage/frontpage.html.erb:21:in `_app_views_frontpage_frontpage_html_erb___4518234645475110659_70230885952360'
# ./spec/controllers/frontpage_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
Here's the controller:
class FrontpageController < ApplicationController
def frontpage
#user = User.new
#sign_up = User.new
end
def sign_up
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
end
end
end
Here's the view, that's causing the error:
<%= form_for #user, :url =>"sign_up" do |form| %>
<%= form.text_field :full_name, :placeholder => "Full name" %>
</br>
<%= form.text_field :email, :placeholder => "Email" %>
</br>
<%= form.text_field :pw, :placeholder => "Password" %>
</br>
<%= form.text_field :username, :placeholder => "Username" %>
</br>
<%= form.submit "Sign up" %>
<% end %>
Here's user.rb:
class User < ActiveRecord::Base
end
Here's schema.rb:
ActiveRecord::Schema.define(:version => 20111106084309) do
create_table "users", :force => true do |t|
t.string "full_name"
t.string "email"
t.string "username"
t.string "pw"
t.datetime "created_at"
t.datetime "updated_at"
end
end
You need to make sure your test database is up to date with all the migrations:
rake db:test:prepare
However, you may have a problem with that as your migrations are broken; you have two migrations named "CreateUsers" which Rails will complain about. It looks like you should delete the more recent one, and then uncomment the t.string :email line in the original one.
Also, if you use bundle exec rake rspec instead of bundle exec rspec spec it'll make sure your database migrations are up to date before running the tests. I just cloned your repo and did this and it passed the tests just fine.
Related
I am new to rails and i am trying to create a simple bookmark table:
def up
create_table :bookmarks do |t|
t.string :path, :null => false
t.integer :user_id, :null => false
t.timestamps
end
add_index :bookmarks, :user_id
add_index :bookmarks, :path
end
then i have this in my contoller:
# GET bookmark/new
# GET bookmark/new.json
def new
#bookmark = Bookmark.new
end
# POST bookmark/new
# POST bookmark/new.json
def create
#bookmark = Bookmark.new(params[:bookmark])
if #bookmark.save
flash[:success] = "Bookmark Saved"
else
flash[:failure] = "Failed !"
end
end
and my view is this:
<%= form_for :bookmark do |bookmark| %>
<%= bookmark.label :path %>
<%= bookmark.text_field :path %>
<%= bookmark.label :user_id %>
<%= bookmark.text_field :user_id %>
<%= bookmark.submit "Add bookmark" %>
<% end %>
finally running rake routes gets this list of routes:
bookmark_index GET /bookmark(.:format) bookmark#index
POST /bookmark(.:format) bookmark#create
new_bookmark GET /bookmark/new(.:format) bookmark#new
edit_bookmark GET /bookmark/:id/edit(.:format) bookmark#edit
bookmark GET /bookmark/:id(.:format) bookmark#show
PUT /bookmark/:id(.:format) bookmark#update
DELETE /bookmark/:id(.:format) bookmark#destroy
and when i try to submit the form i get this error:
Routing Error
No route matches [POST] "/bookmark/new"
Try running rake routes for more information on available routes.
Edit:
Changing :bookmark to #bookmark throws this error:
NoMethodError in Bookmark#new
Showing /media/wahtver/600415AD27D78282/3pces/pces/app/views/shared/_bookmark_form.html.erb where line #1 raised:
undefined method `bookmarks_path' for #<#<Class:0x00000003a48398>:0x007f1034b6b908>
Extracted source (around line #1):
1: <%= form_for #bookmark do |bookmark| %>
2: <%= bookmark.label :path %>
3: <%= bookmark.text_field :path %>
4:
what is the problem?
Thanks
<%= form_for #bookmark do |bookmark| %>
and not
<%= form_for :bookmark do |bookmark| %>
Look more closely at the error message. It's using POST, not GET.
edit: Your routes should be resources :bookmarks.
When you run rake routes it should give you:
bookmarks GET /bookmarks(.:format) bookmarks#index
How did you declare your routes? Did you have on your route.rb file resource :bookmark or resources :bookmarks?
If you see your controller in your create method you have this:
# POST bookmark/new
# POST bookmark/new.json
def create
Pay attention to the comments that rails generate automatically above each method when you use scaffold (i guess you generated the controller with scaffold), it should be POST /bookmarks or POST /bookmark. If you used scaffold for some reason rails generated bad that route.
Show your routes.rb file.
I have a simple model for suggestions in my Rails 3 application. I am trying to add a simple link_to link on the index view that when clicked marks the suggestion as approved.
So far I have the following code:
routes.rb
resources :suggestions do
get :approve
end
suggestions_controller.rb
def approve
#suggestion = Suggestion.find(params[:id])
#suggestion.update_attribute(:approved, 'true')
#suggestion.update_attribute(:approved_on, Time.now)
redirect_to suggestion_path
end
suggestion.rb
attr_accessible :author, :details, :localip, :title, :approved, :approved_on
schema.rb
create_table "suggestions", :force => true do |t|
t.string "title"
t.string "author"
t.text "details"
t.string "localip"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "approved", :default => false
t.datetime "approved_on"
end
index.html.erb (suggestions)
<% if #suggestion.approved? %>
<%= #suggestion.approved_on %>
<% else %>
Not yet approved. (<%= link_to "Approve", approve_suggestion_url(#approve), :method => :put %>)
<% end %>
When using the above code, I get the following exception error:
undefined method `approved?' for nil:NilClass
Am I missing a step out somewhere something?
Most probably, the code you have posted is inside an each loop like
<% #suggestions.each do |suggestion| %>
...
<% if #suggestion.approved? %>
<%= #suggestion.approved_on %>
<% else %>
Not yet approved. (<%= link_to "Approve", approve_suggestion_url(#approve), :method => :put %>)
<% end %>
<% end %>
You need to use suggestion variable instead of #suggestion instance variable. Also, to construct suggestion approve url, you'll need to use suggestion instead of #approve. Code should be like
<% if suggestion.approved? %>
<%= suggestion.approved_on %>
<% else %>
Not yet approved. (<%= link_to "Approve", approve_suggestion_url(suggestion), :method => :put %>)
<% end %>
Also, you should modify your routes.rb to reflect that approve action is a member action.
resources :suggestions do
put :approve, on: :member
end
To understand the difference between member and collection routes, read difference between collection route and member route in ruby on rails?.
am trying to confirm a user account without using the built in devise confirmations controller but i happen to get the following error "uninitialized constant Confirmations Controller". Below is my confirmations controller class.
class ConfirmationsController < Devise::ConfirmationsController
def show
#user = User.find_by_confirmation_token(params[:confirmation_token])
if !#user.present?
render_with_scope :new
end
end
def confirm_account
#user = User.find(params[:user][:confirmation_token])
if #user.update_attributes(params[:user]) and #user.has_password?
#user = User.confirm_by_token(#user.confirmation_token)
flash[:notice] = "Hi " + #user.first_name + " your email has been verified. You can now start shopping and recommending other users to your supplier networks."
redirect_to #user
else
render :action => "show"
end
end
end
And in my routes.rb file i have the following:
devise_for :users, :controllers => { :confirmations => "confirmations" } do
match "confirm_account", :to => "confirmations#confirm_account"
end
And finally i have the following partial:
<p>Welcome <%= #user.first_name %>,</p><br/>
<%= form_for(resource, :url => confirm_account_path) do |f| %>
<%= f.label :email %>
<%= #user.email %>
<%= f.hidden_field :confirmation_token %>
<%= f.submit 'Confirm Account' %>
<p>Thank you for joining. Before you can purchase any item from your supplier or shared network, you will need to confirm your account first. Please follow the link below in order to confirm your account.</p>
<p><%= link_to 'Confirm my account', confirmation_url(#resource, :confirmation_token => #resource.confirmation_token) %></p><br/>
<p>Yours faithfully.</p>
<%end%>
Devise is can be easily modified for your needs. Here is a similar topic, which may be helpful for you:
Override devise registrations controller
I've been reading over this resource as well as this post to try to understand Routes more (currently learning programming/Rails by doing) but am wondering how I can fix the error I'm getting, which is No route matches {:controller=>"profiles", :action=>"show"}.
I get the error working my way through a Rails 3 sign-up process using nested model forms. The sign-up process, as follows:
user = User.new
user.email = ""
user.password = ""
user.profile = Profile.new
user.profile.save
user.save
The sign-up process starts at the homepage with the following form:
<%= form_for :user, :url => signup_path, :html => {:id => 'homepage'} do |f| %>
<div>
...
</div>
<%= f.fields_for :profile do |f| %>
<% end %>
<% end %>
Then the process goes to fill in the profile, then redirect to the new User's profile after this form is completed:
<%= form_for :profile, :html => { :multipart => true } do |f| %>
<div>
...
</div>
<%= f.fields_for :user do |f| %>
<% end %>
<% end %>
I have accepts_nested_attributes_for :user and :profile in their respective models.
My rails server it gives me a bit more detail:
ActionController::RoutingError (No route matches {:controller=>"profile.save", :action=>"show"}):
app/controllers/profiles_controller.rb:15:in `create'
So in my ProfilesController in 'create':
def create
#profile = Profile.new(params[:profile])
if #profile.save
redirect_to profile_path, :notice => 'User successfully added.'
else
render :action => 'new'
end
end
Seems clear that the issue is in profile_path, so my Routes.rb:
post "/signup" => "profiles#create", :as => "signup"
match "skip/signup", :to => "info#signupskip"
match "skip/profiles/new", :to => "profiles#newskip"
root :to => "users#create"
Can anyone help shed light on what I'm doing wrong/missing in my Routes.rb file?
The redirect path should contain the specific profile to redirect to:
if #profile.save
redirect_to profile_path(#profile), :notice => 'User successfully added.'
else
.....
Also the routes should include this line:
get "/profiles/:id" => "profiles#show", as => "profile"
I have an issue on the Learn Rails by Example book Chapter 7 where at the end of the chapter I get these error messages in the rspec spec
1) UsersController should have the right title Failure/Error: get :show, :id => #user ActionController::RoutingError: No route matches {:id=>nil, :controller=>"users", :action=>"show"} # ./spec/controllers/users_controller_spec.rb:36:in `block (2 levels) in '
2) UsersController should include the user's name Failure/Error: get :show, :id => #user ActionController::RoutingError: No route matches {:id=>nil, :controller=>"users", :action=>"show"} # ./spec/controllers/users_controller_spec.rb:41:in `block (2 levels) in '
3) UsersController should have a profile image Failure/Error: get :show, :id => #user ActionController::RoutingError: No route matches {:id=>nil, :controller=>"users", :action=>"show"} # ./spec/controllers/users_controller_spec.rb:46:in `block (2 levels) in '
Below is all relevant code that I have done,
spec/controllers/users_controller_spec.rb
it "should have the right title" do
get :show, :id => #user
response.should have_selector("title", :content => #user.name)
end
it "should include the user's name" do
get :show, :id => #user
response.should have_selectori("h1", :content => #user.name)
end
it "should have a profile image" do
get :show, :id => #user
response.should have_selector("h1>img", :class => "gravatar")
end
end
app/controllers/Users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#title = #user.name
end
app/helpers/users_helper.rb
module UsersHelper
def gravatar_for(user, options = { :size => 50 })
gravatar_image_tag(user.email.downcase, :alt => user.name,
:class => 'gravatar',
:gravatar => options)
end
end
app/views/users/show.html.erb
<%= #user.name %>, <%= #user.email %>
<table class="profile" summary="Profile Information">
<tr>
<td class="main">
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</td>
<td class="sidebar round">
<strong>Name</strong> <%= #user.name %><br />
<strong>URL</strong> <%= link_to user_path(#user), #user %>
</td>
</tr>
</table>
spec/factories.rb
Factory.define :user do |user|
user.name "Michael Hartl"
user.email "mhartl#example.com"
user.password "foobar"
user.password_confirmation "foobar"
end
I think you needed
get :show, :id => #user.id
or even just
get :show, :id => '1'
Instead you were using the entire object as a parameter.
This strongly indicates you didn't set up the #user instance variable in before block for these tests. I would say that was for certain if I could see the whole test, but it certainly looks like it.