Rails FactoryGirl 特征与模型关联 after_create 回调未设置 vanity_url
Rails FactoryGirl trait association with model after_create callback not setting vanity_url
在我的模型中,我有一个 after_create 触发方法的回调:
class Job < ActiveRecord::Base
after_create :update_vanity_url
private
def update_vanity_url
self.vanity_url = '/jobs/' + company.slug + '/' + slug + '/' + id.to_s + '/'
end
end
这为我的工作设置了一个自定义 url,但是,当我尝试在我的优惠券工厂中使用它时,它没有被保存。优惠券是在没有分配作业的情况下创建的。只有在使用优惠券时,它才会与一项工作配对。我将其称为已执行:
FactoryGirl.define do
factory :coupon do
code { rand(25**25) }
percent_discount { rand(100**1) }
start_at { Time.now }
end_at { 30.day.from_now }
trait :executed do |c|
association :job, factory: [:job, :purchased]
c.executed_at { Time.now }
end
end
end
理想情况下,我希望能够调用 FactoryGirl.create(:coupon, :executed)
,但 after_create 从未被调用过...想法?
此处介绍了此设置的更多详细信息
根据下面的问题评论,我添加了我的路线部分和更新:
路线
resources :jobs, only: [:new] do
collection do
post 'new', to: 'jobs#create'
end
get '/review', to: 'reviews#new'
patch '/review', to: 'reviews#update'
get '/payment', to: 'payments#new'
patch '/payment', to: 'payments#update'
end
match '/jobs/:company_slug/:job_slug/:id', via: :get, to: 'jobs#show'
我研究了几个小时,这就是我发现的工作。原来不是FactoryGirl,而是模特本身……我觉得……
def update_vanity_url
self.vanity_url = '/jobs/' + company.slug + '/' + slug + '/' + id.to_s + '/'
save
end
您的实际问题
您询问的问题更多是您进行查找的方式的症状或副作用。
tl;dr:未保存 vanity_url
属性,因为 update_vanity_url
是在 after_create
回调中设置的已经写入数据库。它 是 将其设置在内存中,这就是为什么您的测试可能因此而失败的原因。
这就是为什么将 save
放入回调中可以解决您的问题。它只是在创建后第二次保存 Job
。这是必要的,因为在将其写入数据库之前您不会拥有 id
。
也许是更好的解决方案?
除了路由到 vanity_url
属性之外,您是否对它做任何事情?我问是因为除非您为了速度而对其进行非规范化,否则您可能根本不需要将其存储在模型上。
我唯一想到的是,您可能会使用这些参数来构建 vanity_url
并执行类似 @job = Job.where(vanity_url: vanity_url).first
之类的操作。
在我的模型中,我有一个 after_create 触发方法的回调:
class Job < ActiveRecord::Base
after_create :update_vanity_url
private
def update_vanity_url
self.vanity_url = '/jobs/' + company.slug + '/' + slug + '/' + id.to_s + '/'
end
end
这为我的工作设置了一个自定义 url,但是,当我尝试在我的优惠券工厂中使用它时,它没有被保存。优惠券是在没有分配作业的情况下创建的。只有在使用优惠券时,它才会与一项工作配对。我将其称为已执行:
FactoryGirl.define do
factory :coupon do
code { rand(25**25) }
percent_discount { rand(100**1) }
start_at { Time.now }
end_at { 30.day.from_now }
trait :executed do |c|
association :job, factory: [:job, :purchased]
c.executed_at { Time.now }
end
end
end
理想情况下,我希望能够调用 FactoryGirl.create(:coupon, :executed)
,但 after_create 从未被调用过...想法?
此处介绍了此设置的更多详细信息
根据下面的问题评论,我添加了我的路线部分和更新:
路线
resources :jobs, only: [:new] do
collection do
post 'new', to: 'jobs#create'
end
get '/review', to: 'reviews#new'
patch '/review', to: 'reviews#update'
get '/payment', to: 'payments#new'
patch '/payment', to: 'payments#update'
end
match '/jobs/:company_slug/:job_slug/:id', via: :get, to: 'jobs#show'
我研究了几个小时,这就是我发现的工作。原来不是FactoryGirl,而是模特本身……我觉得……
def update_vanity_url
self.vanity_url = '/jobs/' + company.slug + '/' + slug + '/' + id.to_s + '/'
save
end
您的实际问题
您询问的问题更多是您进行查找的方式的症状或副作用。
tl;dr:未保存 vanity_url
属性,因为 update_vanity_url
是在 after_create
回调中设置的已经写入数据库。它 是 将其设置在内存中,这就是为什么您的测试可能因此而失败的原因。
这就是为什么将 save
放入回调中可以解决您的问题。它只是在创建后第二次保存 Job
。这是必要的,因为在将其写入数据库之前您不会拥有 id
。
也许是更好的解决方案?
除了路由到 vanity_url
属性之外,您是否对它做任何事情?我问是因为除非您为了速度而对其进行非规范化,否则您可能根本不需要将其存储在模型上。
我唯一想到的是,您可能会使用这些参数来构建 vanity_url
并执行类似 @job = Job.where(vanity_url: vanity_url).first
之类的操作。