问题
In my model, I have an after_create callback that triggers the method:
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
This sets up a custom url for my jobs, however, when I try to use this in my coupon factory it is not being saved. The coupon is created without a job assigned. Only when the coupon is used is it paired with one job. I referred to that as executed:
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
Ideally, I would like to be able to call FactoryGirl.create(:coupon, :executed)
which works but the after_create is never called... Thoughts?
More details of this setup are covered here Rails FactoryGirl Factory with optional model association
Per issue comments below, I have added my routes section and updates:
Routes
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'
回答1:
I researched this for hours, and this is what I found to work. It turns out it was not FactoryGirl, rather the model itself... I think...
def update_vanity_url
self.vanity_url = '/jobs/' + company.slug + '/' + slug + '/' + id.to_s + '/'
save
end
回答2:
Your actual question
The problem you're asking about is more a symptom or side effect of how you're doing your lookup.
tl;dr: The vanity_url
attribute is not being saved because update_vanity_url
is set on an after_create
callback when the record has already been written to the database. It is setting it in memory which is why your tests might've been tripped up by this.
That's why putting save
in the callback fixed your issue. It's simply saving a Job
a second time after it's created. This is necessary because you wouldn't have the id
before it was written to the database.
Maybe a better solution?
Are you doing anything with the vanity_url
attribute besides routing to it? I ask because unless you're denormalizing this for speed you may not need to store this on the model at all.
The only thing I came up with is that you might be using those params to construct the vanity_url
and doing something like @job = Job.where(vanity_url: vanity_url).first
or something.
来源:https://stackoverflow.com/questions/35950470/rails-factorygirl-trait-association-with-model-after-create-callback-not-setting