2016-03-19 4 views
0

Когда я пытаюсь запустить FactoryGirl.create(:job, :purchased) Я получаю следующую ошибку. Я уже давно сражаюсь с этим, и я считаю, что у меня проблема плюрализации.factorygirl create model association NoMethodError: undefined method

Выпуск

enter image description here

Модели

class Job < ActiveRecord::Base 
    belongs_to :company 
    belongs_to :category 
    has_one :coupon 
    has_many :payments 
end 

class Payment < ActiveRecord::Base 
    belongs_to :job 
    belongs_to :coupon 
end 

class Coupon < ActiveRecord::Base 
    belongs_to :job 
end 

Фабрика

FactoryGirl.define do 
    factory :job do 
    category 
    company 
    title { FFaker::Company.position } 
    location { "#{FFaker::Address.city}, #{FFaker::AddressUS.state}" } 
    language_list { [FFaker::Lorem.word] } 
    short_description { FFaker::Lorem.sentence } 
    description { FFaker::HTMLIpsum.body } 
    application_process { "Please email #{FFaker::Internet.email} about the position." } 

    trait :featured do |job| 
     job.is_featured true 
    end 

    trait :reviewed do |job| 
     job.reviewed_at { Time.now } 
    end 

    trait :purchased do |job| 
     job.reviewed_at { Time.now } 
     job.start_at { Time.now } 
     job.end_at { AppConfig.product['settings']['job_active_for_day_num'].day.from_now } 
     job.paid_at { Time.now } 
     association :payment, factory: :payment 
    end 

    trait :expired do |job| 
     start_at = (200..500).to_a.sample.days.ago 
     job.reviewed_at { start_at } 
     job.start_at { start_at } 
     job.end_at { |j| j.start_at + AppConfig.product['settings']['job_active_for_day_num'].days } 
     job.paid_at { start_at } 
     # TBD ADD PAYMENT 
    end 
    end 
end 

Частичная схема

create_table "payments", force: :cascade do |t| 
    t.decimal "price_paid",   precision: 8, scale: 2, default: 0.0 
    t.string "stripe_customer_token" 
    t.datetime "created_at",   null: false 
    t.datetime "updated_at",   null: false 
    end 

    create_table "jobs", force: :cascade do |t| 
    t.string "title",    limit: 50,     null: false 
    t.string "slug",    limit: 250,     null: false, index: {name: "index_jobs_on_slug"} 
    t.string "vanity_url",   limit: 250 
    t.string "location",   limit: 100,     null: false 
    t.string "short_description", limit: 250,     null: false 
    t.text  "description",   null: false 
    t.text  "application_process", null: false 
    t.boolean "is_featured",   default: false 
    t.datetime "start_at" 
    t.datetime "end_at" 
    t.datetime "created_at",   null: false 
    t.datetime "updated_at",   null: false 
    t.integer "company_id",   index: {name: "index_jobs_on_company_id"}, foreign_key: {references: "companies", name: "fk_jobs_company_id", on_update: :no_action, on_delete: :no_action} 
    t.datetime "deleted_at",   index: {name: "index_jobs_on_deleted_at"} 
    t.integer "category_id",   index: {name: "index_jobs_on_category_id"}, foreign_key: {references: "categories", name: "fk_jobs_category_id", on_update: :no_action, on_delete: :no_action} 
    t.datetime "paid_at" 
    t.datetime "reviewed_at" 
    t.integer "payment_id",   index: {name: "index_jobs_on_payment_id"}, foreign_key: {references: "payments", name: "fk_jobs_payment_id", on_update: :no_action, on_delete: :no_action} 
    end 

    create_table "coupons", force: :cascade do |t| 
    t.integer "code",    limit: 8, null: false, index: {name: "index_coupons_on_code", unique: true} 
    t.integer "percent_discount", limit: 2, null: false 
    t.datetime "start_at",   null: false 
    t.datetime "end_at",   null: false 
    t.datetime "executed_at" 
    t.datetime "deleted_at",  index: {name: "index_coupons_on_deleted_at"} 
    t.datetime "created_at",  null: false 
    t.datetime "updated_at",  null: false 
    t.integer "job_id",   index: {name: "index_coupons_on_job_id"}, foreign_key: {references: "jobs", name: "fk_coupons_job_id", on_update: :no_action, on_delete: :no_action} 
    t.integer "payment_id",  index: {name: "index_coupons_on_payment_id"}, foreign_key: {references: "payments", name: "fk_coupons_payment_id", on_update: :no_action, on_delete: :no_action} 
    end 

Обновления в чате ниже

create_table "jobs", force: :cascade do |t| 
    t.string "title",    limit: 50,     null: false 
    t.string "slug",    limit: 250,     null: false, index: {name: "index_jobs_on_slug"} 
    t.string "vanity_url",   limit: 250 
    t.string "location",   limit: 100,     null: false 
    t.string "short_description", limit: 250,     null: false 
    t.text  "description",   null: false 
    t.text  "application_process", null: false 
    t.boolean "is_featured",   default: false 
    t.datetime "start_at" 
    t.datetime "end_at" 
    t.datetime "created_at",   null: false 
    t.datetime "updated_at",   null: false 
    t.integer "company_id",   index: {name: "index_jobs_on_company_id"}, foreign_key: {references: "companies", name: "fk_jobs_company_id", on_update: :no_action, on_delete: :no_action} 
    t.datetime "deleted_at",   index: {name: "index_jobs_on_deleted_at"} 
    t.integer "category_id",   index: {name: "index_jobs_on_category_id"}, foreign_key: {references: "categories", name: "fk_jobs_category_id", on_update: :no_action, on_delete: :no_action} 
    t.datetime "paid_at" 
    t.datetime "reviewed_at" 
    end 

    create_table "coupons", force: :cascade do |t| 
    t.integer "code",    limit: 8, null: false, index: {name: "index_coupons_on_code", unique: true} 
    t.integer "percent_discount", limit: 2, null: false 
    t.datetime "start_at",   null: false 
    t.datetime "end_at",   null: false 
    t.datetime "executed_at" 
    t.datetime "deleted_at",  index: {name: "index_coupons_on_deleted_at"} 
    t.datetime "created_at",  null: false 
    t.datetime "updated_at",  null: false 
    t.integer "job_id",   index: {name: "index_coupons_on_job_id"}, foreign_key: {references: "jobs", name: "fk_coupons_job_id", on_update: :no_action, on_delete: :no_action} 
    end 

    create_table "payments", force: :cascade do |t| 
    t.decimal "price_paid",   precision: 8, scale: 2, default: 0.0 
    t.string "stripe_customer_token" 
    t.datetime "created_at",   null: false 
    t.datetime "updated_at",   null: false 
    t.integer "job_id",    index: {name: "index_payments_on_job_id"}, foreign_key: {references: "jobs", name: "fk_payments_job_id", on_update: :no_action, on_delete: :no_action} 
    t.integer "coupon_id",    index: {name: "index_payments_on_coupon_id"}, foreign_key: {references: "coupons", name: "fk_payments_coupon_id", on_update: :no_action, on_delete: :no_action} 
    end 

Ошибки enter image description here

TRAITS РАБОЧИЕ

trait :purchased do |job| 
    job.reviewed_at { Time.now } 
    job.start_at { Time.now } 
    job.end_at { AppConfig.product['settings']['job_active_for_day_num'].day.from_now } 
    job.paid_at { Time.now } 
    payments { |j| [j.association(:payment)] } 
end 

ответ

1

В вашем trait ваши определяют association :payment, factory: :payment но работа has_many платежей.

Для работы, ваши модели должны быть:

class Job < ActiveRecord::Base 
    belongs_to :payment 
end 

class Payment < ActiveRecord::Base 
    has_many :jobs 
end 

Если вы хотите сохранить вашу модель, как у вас есть и создать черт с работой, содержащей нескольких платежей, что вам нужно сделать что-то вроде этого:

How to set up factory in FactoryGirl with has_many association

+0

спасибо за сообщение, да, я стараюсь, чтобы иметь работу с большим количеством платежных записей, так что я могу отслеживать нашивки попытки –

+0

Если вы хотите сделать это, ваши таблицы неверны. Таблица платежей должна иметь 'job_id', чтобы соответствовать вашим отношениям модели. – Leantraxxx

+0

Я обновил схему, но я все равно получаю ту же ошибку –

Смежные вопросы