Good night. I have some problems with my first rails app. I have two models User and Profile. It have association has_one and belongs_to
User.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me,:username
validates :username, presence: true
has_one :profile, dependent: :destroy
end
Profile.rb
class Profile < ActiveRecord::Base
attr_accessible :aboutme, :city, :gamelevel, :phone
belongs_to :user
validates :user_id, presence: true
validates :phone, length: { in: 3..12 }
validates :phone, numericality: { only_integer: true }
end
There are my factories:
factories.rb
FactoryGirl.define do
factory :user do
username "Valik Leontiev"
email "Leontiev@example.com"
password "foobaryea"
password_confirmation "foobaryea"
end
factory :profile do
city "Vladikavkaz"
gamelevel "M1"
phone "8029383744"
aboutme "Hello, my friend!"
user #association with user
end
end
And I've tested my model with rspec:
user_spec.rb require 'spec_helper'
describe User do
before do
@user = User.new(username: "Example User", email: "user@example.com",
password: "foobaryea", password_confirmation: "foobaryea")
end
subject { @user }
describe "profiles associations" do
before { @user.save }
let(:profile) do
FactoryGirl.create(:profile, user: @user)
end
it "should destroy associated profile" do
@profile = @user.profile
@user.destroy
@profile.should_not be_empty
Profile.find_by_id(profile.id).should be_nil
end
it "should have not more then one profile" do
Profile.where(user_id: @user.id).count > 2
should_not be true
end
end
end
And I had one failure in "should destroy associated profile" blocks: NoMethodError: undefined method `empty?'. so, how I am undersanding, @user.profile is nil, why association has not building? I've add "user" in profile factories for associate. Help me, please
Nothing is necessarily wrong with your Rails code and @user.profile
may be perfectly valid. The ActiveRecord
class does not have an empty?
method, which is what the is_empty
matcher relies on. You should be using some other matcher if you want to test that the @profile
object is still valid after the associated user is destroyed.
Here's output from a console session that shows the creation of a User
, the creation of an associated Profile
, the destroying of the User
and the impact of the in-memory and saved Profile
.
2.0.0p247 :001 > user = User.create
(0.2ms) BEGIN
Binds are [#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007ff0b24c1d50 @oid_type=#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::Timestamp:0x007ff0b2962440>, @array=false, @name="updated_at", @sql_type="timestamp without time zone", @null=true, @limit=nil, @precision=nil, @scale=nil, @type=:datetime, @default=nil, @primary=false, @coder=nil>, Fri, 12 Jul 2013 14:12:19 UTC +00:00]
SQL (10.3ms) INSERT INTO "users" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", Fri, 12 Jul 2013 14:12:19 UTC +00:00], ["updated_at", Fri, 12 Jul 2013 14:12:19 UTC +00:00]]
(0.7ms) COMMIT
=> #<User id: 6, created_at: "2013-07-12 14:12:19", updated_at: "2013-07-12 14:12:19">
2.0.0p247 :002 > profile = Profile.create(user_id: user.id)
(0.3ms) BEGIN
Binds are [#<ActiveRecord::ConnectionAdapters::PostgreSQLColumn:0x007ff0b41d3060 @oid_type=#<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID::Timestamp:0x007ff0b2962440>, @array=false, @name="updated_at", @sql_type="timestamp without time zone", @null=true, @limit=nil, @precision=nil, @scale=nil, @type=:datetime, @default=nil, @primary=false, @coder=nil>, Fri, 12 Jul 2013 14:12:39 UTC +00:00]
SQL (3.3ms) INSERT INTO "profiles" ("created_at", "updated_at", "user_id") VALUES ($1, $2, $3) RETURNING "id" [["created_at", Fri, 12 Jul 2013 14:12:39 UTC +00:00], ["updated_at", Fri, 12 Jul 2013 14:12:39 UTC +00:00], ["user_id", 6]]
(0.4ms) COMMIT
=> #<Profile id: 4, created_at: "2013-07-12 14:12:39", updated_at: "2013-07-12 14:12:39", user_id: 6>
2.0.0p247 :003 > user.destroy
(0.4ms) BEGIN
Binds are nil
Profile Load (1.9ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 ORDER BY "profiles"."id" ASC LIMIT 1 [["user_id", 6]]
Binds are nil
SQL (0.8ms) DELETE FROM "profiles" WHERE "profiles"."id" = $1 [["id", 4]]
Binds are nil
SQL (0.5ms) DELETE FROM "users" WHERE "users"."id" = $1 [["id", 6]]
(0.4ms) COMMIT
=> #<User id: 6, created_at: "2013-07-12 14:12:19", updated_at: "2013-07-12 14:12:19">
2.0.0p247 :004 > Profile.find_by_id(4)
Profile Load (0.7ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."id" = 4 LIMIT 1
=> nil
2.0.0p247 :005 > profile
=> #<Profile id: 4, created_at: "2013-07-12 14:12:39", updated_at: "2013-07-12 14:12:39", user_id: 6>
2.0.0p247 :006 >
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.