我有三个模型用户(作者),它包含设计逻辑:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :questions
has_many :answers
end
问题:
# Model for Question
class Question < ActiveRecord::Base
has_many :answers, dependent: :destroy
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
validates :title, presence: true, length: { maximum: 100 }
validates :body, presence: true, length: { minimum: 10 }
validates :author, presence: true
end
并回答:
# Model for Answer
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
validates :body, presence: true, length: { minimum: 10 }
validates :question_id, presence: true
validates :author, presence: true
end
和他们的工厂:
FactoryGirl.define do
sequence :email do |n|
"email-#{n}@example.com"
end
sequence :password do |n|
"testpassword#{n}"
end
factory :user, aliases: [:author] do
email
# tried sequence generator and fixed password - both have no impact on result
# password '1234567890'
# password_confirmation '1234567890'
password
end
end
FactoryGirl.define do
factory :answer do
body 'Answer Body'
author
question
end
factory :nil_answer, class: 'Answer' do
question
body nil
end
end
FactoryGirl.define do
factory :question do
title 'Question Title'
body 'Question Body'
author
factory :question_with_answers do
after(:create) do |question|
# changing create_list to create has no impact on result
# create_list(:answer, 2, question: question)
create(:answer, question: question)
end
end
end
end
测试代码:
require 'rails_helper'
feature 'Delete answer', %q{
By some reason
As an authenticated user
I want to delete answer
} do
given(:question) { create(:question_with_answers) }
given(:user) { create(:user) }
given(:ans) { create(:answer) }
scenario 'Answer author password should not be nil' do
expect(question.answers.first.author.password).to_not be_nil
# question.author.password and ans.author.password return not nil
# I need password to do:
# visit new_user_session_path
# fill_in 'Email', with: user.email
# fill_in 'Password', with: user.password
# click_on 'Log in'
end
end
任何人都可以解释为什么以下给出的陈述:
given(:question) { create(:question_with_answers) }
创建问题对象:
question.author.password #=> '1234567890'
但:
question.answers.first.author.password #=> nil
为什么方法&#34;创建&#34;正确地实例化问题的作者(设置字段密码),但是&#34; create_list&#34;在&#34;之后&#34;回调是否使用nil字段创建作者?
rails 4.2.5,ruby 2.3.0,设计3.5.6,看守1.2.6,factory_girls_rails 4.6.0(4.5.0)
答案 0 :(得分:3)
Devise(和大多数身份验证库)加密密码,不允许您从数据库中检索的模型访问密码。密码可以通过内存中的读取器方法暂时可用,但如果从数据库中检索记录,则无法使用该密码。
如果你这样做:
user = User.new(password: "example")
p user.password
我猜你会看到"example"
。
但如果你这样做:
user = User.first
p user.password
我打赌你会看到nil
(假设你的数据库中有用户记录)。
当您查询像question.answers.first.author
这样的关联代理时,它会再次访问数据库以找到答案和作者。这意味着您正在使用不再具有密码的其他实例。