【发布时间】:2019-03-05 21:41:21
【问题描述】:
背景:
我正在尝试创建一个与 has_one/belongs_to 相关的 FactoryBot 对象
User has_one Car
Car has_one Style
Style has an attribute {style_number:"1234"}
问题
我的控制器引用了用户,用户 has_one Car,Car has_one Style,我需要在 FactoryBot 中设置这些值。
如何创建一个同时拥有 Car 对象和 Style 对象的用户?
我阅读了文档https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md
但是,我不明白他们如何推荐这样做。想通了,我需要嵌套这三个对象,但对语法感到困惑。
控制器
before_action :authenticate_user!
before_action :set_steps
before_action :setup_wizard
include Wicked::Wizard
def show
@user = current_user
@form_object = form_object_model_for_step(step).new(@user)
render_wizard
end
private
def set_steps
if style_is_1234
self.steps = car_steps.insert(1, :style_car)
else
self.steps = car_steps
end
end
def style_is_1234
if params.dig(:form_object, :style_number)
(params.dig(:form_object, :style_number) & ["1234"]).present?
else
(current_user.try(:car).try(:style).try(:style_number) & ["1234"]).present?
end
end
def car_steps
[:type,:wheel, :brand]
end
Rspec 测试
工厂:用户
FactoryBot.define do
factory :user, class: User do
first_name { "John" }
last_name { "Doe" }
email { Faker::Internet.email }
password { "somepassword" }
password_confirmation { "some password"}
end
end
方法之前
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:user]
user = FactoryBot.create(:user)
sign_in user
测试
用户需要登录并且 User.car.style.style_number 需要设置为“1234”context "Requesting with second step CarStyle" do
it "should return success" do
get :show, params: { :id => 'car_style' }
expect(response.status).to eq 200
end
end
目前此测试失败,因为 User.Car.Style.style_number 未设置为“1234”。
试用 1 (https://github.com/thoughtbot/factory_bot_rails/issues/232)
FactoryBot.define do
factory :user, class: User do
first_name { "John" }
last_name { "Doe" }
email { Faker::Internet.email }
password { "somepassword" }
password_confirmation { "some password"}
car
end
end
FactoryBot.define do
factory :car, class: Car do
make { "Holden" }
model { "UTE" }
end
end
FactoryBot.define do
factory :style, class: Style do
color { "blue" }
for_car
trait :for_car do
association(:styable, factory: :car)
end
end
end
路径 1 出错
系统堆栈错误: 堆栈层太深
步道 2
我试过srng的推荐
编辑:对于多态关联尝试;
FactoryBot.define do
factory :car, class: Car do
make { "Holden" }
model { "UTE" }
association :stylable, factory: :style
end
end
得到错误:
ActiveRecord::RecordInvalid:验证失败:样式必须存在
我认为这是 Rails 5 的问题。 https://github.com/rails/rails/issues/24518
但是,我想通过添加 optional:true 来保留我的代码。有什么办法吗?
步道 3
FactoryBot.define do
factory :car, class: Car do
make { "Holden" }
model { "UTE" }
after(:create) do |car|
create(:style, stylable: car)
end
end
end
尝试了 Srng 的第二个建议,虽然它对他有用,但我得到了一个稍微不同的错误:
ActiveRecord::RecordInvalid: 验证失败:用户必须存在
【问题讨论】:
标签: ruby-on-rails rspec factory-bot ruby-on-rails-5.2