Michael Hartl Tutorial Chapter 6 - Syntax error - ruby-on-rails

I'm working on Michael Hartl's Tutorial. I'm on Chapter 6. I am up to user validation. The code below is what I was told to use, but it doesn't work. I get the error message syntax error, unexpected end-of-input, expecting keyword_end (SyntaxError). I don't see a syntax error. Any suggestions?
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
#user.should_not be_valid
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
#user.should be_valid
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
end

I recommend that you indent your code, that way it'll be much more obvious where end keywords should go (and you'll see immediately that you're missing one). (Hartl does throughout the book.)
For example:
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
end
If the indentation doesn't match up anywhere, it should jump out at you, then you'll know there's a problem.

require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
#user.should_not be_valid
end
end # you've missed it
end # and this one
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
#user.should be_valid
end
end #
end # and two more
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
end

In Ruby, do .. end specifies a block. It goes like:
... do
.. Some Code Here ...
end
You should indent your code and have better look at the missing end.
In general, Its a convention in Ruby to use 2 spaces Or a tab character with length of 2 spaces to indent your code.

Related

No method error - save from rubystutorial.org

I've been following along Hartl's book at rubystutorial.org and stuck on this error
When I run rspec tests it tells me that the method (save) does not exist for user
Here's my code and test. I can't find what's wrong with it and why the method doesn't exist within #user
user_spec.rb
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "shoud be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo. foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
expect(#user).not_to be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
end
And my user.rb
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates(:name, presence: true, length: { maximum: 50 } )
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates(:email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false } )
end
Exact error is
Failures:
1) User when email address is already taken
Failure/Error: user_with_same_email.save
NoMethodError:
undefined method `save' for "USER#EXAMPLE.COM":String
# ./spec/models/user_spec.rb:55:in `block (3 levels) in <top (required)>'
Finished in 0.411 seconds
24 examples, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:58 # User when email address is already take
You are defining a user and then change it on string (email, so email has no save method) in the next lines:
user_with_same_email = #user.dup
user_with_same_email = #user.email.upcase
user_with_same_email.save
You should change it for this:
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
Object
The problem here can be seen with the error itself:
undefined method `save' for "USER#EXAMPLE.COM":String
The problem you have is not that .save is unavailable, but that the object you're trying to call it on is unable to process it.
The problem is specifically to do with this line:
user_with_same_email = #user.email.upcase
--
Fix
The issue is you're setting the user_with_same_email variable as #user.email.upcase. You can do what zishe suggested (to set the email attribute of the new variable)
I don't really understand what you're trying to achieve - as your User model sets the email to downcase on the before_save callback.

Rails Tutorial by Michael Hartl Chapter 6 Authenticate User

I can't for the life of me seem to figure out why these three tests aren't passing. I'm pretty new with rails but I feel as though I've tried about everything, at least according to the tutorial. I'm sure its something obvious but my attempts to find an answer have been in vain. My failed tests are as follows(pulled from Michael Hartl's Rails Tutorial). Thanks.
Failures:
1) User when password is not present return value of authenticate method with valid password
Failure/Error: it { should eq found_user.authenticate(#user.password) }
NoMethodError:
undefined method authenticate' for nil:NilClass
# ./spec/models/user_spec.rb:94:inblock (5 levels) in '
2) User when password is not present return value of authenticate method with invalid password
Failure/Error: let(:user_for_invalid_password) { found_user.authenticate("invalid") }
NoMethodError:
undefined method authenticate' for nil:NilClass
# ./spec/models/user_spec.rb:98:inblock (5 levels) in '
# ./spec/models/user_spec.rb:100:in `block (5 levels) in '
3) User when password is not present return value of authenticate method with invalid password
Failure/Error: let(:user_for_invalid_password) { found_user.authenticate("invalid") }
NoMethodError:
undefined method authenticate' for nil:NilClass
# ./spec/models/user_spec.rb:98:inblock (5 levels) in '
# ./spec/models/user_spec.rb:101:in `block (5 levels) in '
User_spec tests
require 'spec_helper'
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:authenticate) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
it "should be valid" do
expect(#user).to be_valid
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = 'a' * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
expect(#user).not_to be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when password is not present" do
before do
#user = User.new(name:"Example User", email: "user#example.com",
password: " ", password_confirmation: " ")
end
it { should_not be_valid }
describe "when password does not match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "with a password thats too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by(email: #user.email) }
describe "with valid password" do
it { should eq found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_invalid_password }
specify { expect(user_for_invalid_password).to be_false }
end
end
end
end
User model
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
end
You are getting the error as found_user is nil.
Thats because you are not closing when password is not present describe block properly.
So what happens is, this invalid #user is set with a blank password and its been carried forward till your failing test case.
describe "when password is not present" do
before do
#user = User.new(name:"Example User", email: "user#example.com",
password: " ", password_confirmation: " ")
end
it { should_not be_valid }
end ### Add end here
Also, remove the very last end from the bottom of the file.

Syntax error "syntax error, unexpected end-of-input, expecting keyword_end (SyntaxError)"

I can't run my Rspec user_spec.rb test due to a syntax error. Too many "end" perhaps in 2 different files? I've added and deleted 'end' in certain places without success.
Syntax error "syntax error, unexpected end-of-input, expecting keyword_end (SyntaxError)"
require 'spec_helper'
user_spec.rb
describe User do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: "foobar", password_confirmation: "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should be_valid }
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
before do
#user = User.new(name: "Example User", email: "user#example.com")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should be_valid }
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
expect(#user).not_to be_valid
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.save
end
describe "when password is not present" do
before do
#user = User.new(name: "Example User", email: "user#example.com",
password: " ", password_confirmation: " ")
end
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
user_pages_spec.rb
require 'spec_helper'
describe "User pages" do
subject { page }
describe "signup" do
before { visit signup_path }
it { should have_content('Sign up') }
it { should have_title(full_title('Sign up')) }
end
end
let(:submit) { "Create my account" }
describe "with invalid information" do
it "should not create a user" do
expect { click_button submit }.not_to change(User, :count)
end
end
describe "with valid information" do
before do
fill_in "Name", with: "Example User"
fill_in "Email", with: "user#example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
end
end
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
end
Terminal Output
/usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `load': /Users/Abraham/code/sample_app/spec/models/user_spec.rb:85: syntax error, unexpected end-of-input, expecting keyword_end (SyntaxError)
from /usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `block in load_spec_files'
from /usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `each'
from /usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/configuration.rb:819:in `load_spec_files'
from /usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/command_line.rb:22:in `run'
from /usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:80:in `run'
from /usr/local/rvm/gems/ruby-2.0.0-p247#railstutorial_rails_4_0/gems/rspec-core-2.13.1/lib/rspec/core/runner.rb:17:in `block in autorun'
It seems that you have a bunch of describes that never have ends keywords, starting with describe "when email format is invalid" do until describe "when email address is already taken" do
Put an end on those guys and you're probably done =)
Do you perhaps have one too many here?
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
end
Just posting in case it help someone else. The cause of this error for me was a missing do after creating a form with form_with. Hope that may help someone else
$ rails server -b $IP -p $PORT - that solved the same problem for me

Not sure why getting Syntax Errors

I'm following the online ruby on rails tutorial using an imac with OSx10.8 using rvm and ruby 1.8.7. When running bundle exec rspec spec/ I get these errors
/Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load': /Users/hetzerbr/sample_app/spec/models/user_spec.rb:88: syntax error, unexpected kEND, expecting $end (SyntaxError)
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/activesupport-3.2.13/lib/active_support/dependencies.rb:245:in `load'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load_spec_files'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `map'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/rspec-core-2.11.1/lib/rspec/core/configuration.rb:780:in `load_spec_files'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/rspec-core-2.11.1/lib/rspec/core/command_line.rb:22:in `run'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:66:in `run'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/gems/rspec-core-2.11.1/lib/rspec/core/runner.rb:8:in `autorun'
from /Users/hetzerbr/.rvm/gems/ruby-1.8.7-p374/bin/ruby_noexec_wrapper:14
My user_spec.rb file looks like this, I think the error might be that I placed an end somewhere that I should not have or I might be missing and end somewhere:
require 'spec_helper'
describe User do
before do
#user = User.new(:name => "Example User", :email => "user#example.com", :password => "foobar", :password_confirmation => "foobar")
end
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:authenticate) }
it { should be_valid }
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.
foo#bar_baz.com foo#bar+baz.com foo#bar..com]
addresses.each do |invalid_address|
#user.email = invalid_address
expect(#user).not_to be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org frst.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
expect(#user).to be_valid
end
end
end
end
describe "email address with mixed case" do
let(:mixed_case_email) { "Foo#ExAMPle.CoM" }
it "should be saved as all lower-case" do
#user.email = mixed_case_email
#user.save
expect(#user.reload.email).to eq mixed_case_email.downcase
end
end
describe "when password is not present" do
before do
#user = User.new(:name => "Example User", :email => "user#example.com",
:password => " ", :password_confirmation => " ")
end
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
end
describe "with a password that's too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by(:email => #user.email) }
describe "with valid password" do
it { should eq found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not eq user_for_invalid_password }
specify { expect(user_for_invalid_password).to be_false }
end
end
end
Some of your describe blocks don't have an 'end'
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
should be..
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
It is a hash you must pass to the new() method while mass-assign , try it in {}
#user = User.new( { :name => "Example User", :email => "user#example.com", :password => "foobar", :password_confirmation => "foobar" } )
at your error line : syntax error, unexpected keyword_end, expecting $end (SyntaxError)
kEND means end of file but $end means end keyword, you must close your describe do body of codes each by one end

Test for destroying associated records when object is destroyed failing in rails app

Im stuck on the test in listing 10.15 of Michael Hartls ruby on rails tutorial (http://ruby.railstutorial.org/chapters/user-microposts#code-micropost_dependency_test). My user_spec.rb is as follows
require 'spec_helper'
describe User do
before { #user = User.new(name: "Example User", email: "user#example.com",password: "foobar", password_confirmation: "foobar") }
subject { #user }
it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:remember_token) }
it { should respond_to(:admin) }
it { should respond_to(:authenticate) }
it { should respond_to(:microposts) }
it { should be_valid }
it { should_not be_admin }
describe "with admin attribute set to 'true'" do
before do
#user.save!
#user.toggle!(:admin)
end
it { should be_admin }
end
describe "when name is not present" do
before { #user.name = " " }
it { should_not be_valid }
end
describe "when email is not present" do
before { #user.email = " " }
it { should_not be_valid }
end
describe "when name is too long" do
before { #user.name = "a" * 51 }
it { should_not be_valid }
end
describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo. foo#bar_baz.com foo#bar+baz.com]
addresses.each do |invalid_address|
#user.email = invalid_address
#user.should_not be_valid
end
end
end
describe "when email format is valid" do
it "should be valid" do
addresses = %w[user#foo.COM A_US-ER#f.b.org first.lst#foo.jp a+b#baz.cn]
addresses.each do |valid_address|
#user.email = valid_address
#user.should be_valid
end
end
end
describe "when email address is already taken" do
before do
user_with_same_email = #user.dup
user_with_same_email.email = #user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe "when password is not present" do
before { #user.password = #user.password_confirmation = " "}
it { should_not be_valid }
end
describe "when password doesn't match confirmation" do
before { #user.password_confirmation = "mismatch" }
it { should_not be_valid }
end
describe "when password confirmation is nil" do
before { #user.password_confirmation = nil }
it { should_not be_valid }
end
describe "return value of authenticate method" do
before { #user.save }
let(:found_user) { User.find_by_email(#user.email) }
describe "with valid password" do
it { should == found_user.authenticate(#user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end
describe "with a password that's too short" do
before { #user.password = #user.password_confirmation = "a" * 5 }
it { should be_invalid }
end
describe "remember token" do
before { #user.save }
its(:remember_token) { should_not be_blank }
end
describe "micropost associations" do
before { #user.save }
let!(:older_micropost) do
FactoryGirl.create(:micropost, user:#user, created_at: 1.day.ago)
end
let!(:newer_micropost) do
FactoryGirl.create(:micropost, user:#user, created_at: 1.hour.ago)
end
it "should have the right microposts in the right order" do
#user.microposts.should == [newer_micropost, older_micropost]
end
it "should destroy the associated microposts" do
microposts = #user.microposts.dup
#user.destroy
microposts.should_not be_empty
microposts.each do |micropost|
Micropost.find_by_id(micropost.id).should be_nil
end
end
end
end
When i run the tests i get the following error :
1) User micropost associations should destroy the associated microposts
Failure/Error: Micropost.find_by_id(micropost.id).should be_nil
expected: nil
got: #<Micropost id: 2, content: "Lorem ipsum", user_id: nil, created_at: "2012-12-19 09:49:24", updated_at: "2012-12-19 10:49:24">
# ./spec/models/user_spec.rb:133:in `block (4 levels) in <top (required)>'
# ./spec/models/user_spec.rb:132:in `each'
# ./spec/models/user_spec.rb:132:in `block (3 levels) in <top (required)>'
In my user.rb i have added the dependent :destroy as follows, which is required for the test to pass.
has_many :microposts, dependent: :destroy
Why is the test still failing ?
Thank You
I would encourage you not to do something like:
expect { #user.destroy }.to change(User, :count).by(-1)
This only tests the any user was deleted, it does not confirm that the correct records were deleted. Instead, I would do something like this
#user.destroy
expect { #user.reload }.to raise_error ActiveRecord::RecordNotFound
This ensures the correct user was deleted.
Consider testing with a more abbreviated expect .. to change test:
it "destroys the associated microposts" do
expect { #user.destroy }.to change(Micropost, :count).by(-2)
end
Replace the -2 with whatever change value you'd expect. For example, if it deletes 1 Micropost record, then change it to -1.
For some reason the microposts are not linked to the user, a you can see by user_id: nil:
Micropost id: 2, content: "Lorem ipsum", user_id: nil, created_at: "2012-12-19 09:49:24", updated_at: "2012-12-19 10:49:24"
I believe the belongs_to: user association is missing in the Micropost model.

Resources