0

我有一个非常简单的聚关联设置。我试图验证令牌只存在于提供者或商店,而不是两者。当我使用pry时,这些验证工作正常,但是,我的重构已经让工厂停工。工厂女孩与多态关联和接受嵌套属性失败验证

问题

如果您创建了一个令牌即FactoryGirl.create店(:店,:with_authentication_token)它吹起来,因为店无法获得创建并保存像FG试图处理它?任何人都可以指出我正确的方向来设置工厂?

错误

ActiveRecord::RecordInvalid: Validation failed: Owner can't be blank

眼下供应商工厂的工作,因为它是父。

在PRY工作?

shop = FactoryGirl.build(:shop) 
shop.authentication_token_attributes = { token: 'test', owner: shop } 
shop.save 

create_table "authentication_tokens", force: :cascade do |t| 
    t.string "token",  limit: 255, null: false 
    t.datetime "created_at",    null: false 
    t.datetime "updated_at",    null: false 
    t.integer "owner_id", limit: 4, null: false 
    t.string "owner_type", limit: 255, null: false 
    end 

工厂

FactoryGirl.define do 
    factory :shop do 
    provider 
    ... 

    trait :with_authentication_token do 
     before(:create) do |shop| 
     create(:authentication_token, owner: shop) 
     end 
     after(:build) do |shop| 
     build(:authentication_token, owner: shop) 
     end 
    end 

    trait :inactive do 
     active { false } 
    end 
    end 
end 

模型

class Shop < ActiveRecord::Base 
    belongs_to :provider 
    has_one :authentication_token, as: :owner, dependent: :destroy 

    accepts_nested_attributes_for(:authentication_token, update_only: true) 

    ... 

    validates :authentication_token, presence: true, if: :shop_is_owner? 

    ... 

    private 

    def shop_is_owner? 
    return false if provider.authentication_token 
    true 
    end 
end 

class Provider < ActiveRecord::Base 
    ... 

    has_many :shops 
    has_one :authentication_token, as: :owner, dependent: :destroy 

    ... 

    accepts_nested_attributes_for(:authentication_token, update_only: true) 

end 


class AuthenticationToken < ActiveRecord::Base 
    belongs_to :owner, polymorphic: true 

    validates :token, 
      length: { maximum: 245 }, 
      presence: true, 
      uniqueness: true 

    validates :owner, presence: true 

    validate :unique_auth_token 

    def shop 
    return owner if owner_type == 'Shop' 
    end 

    def provider 
    return owner if owner_type == 'Provider' 
    end 

    private 

    def unique_auth_token 
    errors.add(:base, I18n.t('activerecord.errors.models.shop.no_auth_token_sharing')) if shop && shop.provider.authentication_token 
    end 
end 

回答

3

,所以你不能触发节省两个模型相关的模型实例和相关的前

trait :with_authentication_token do 
    before(:create) do |shop| 
    create(:authentication_token, owner: shop) 
    end 
    after(:build) do |shop| 
    build(:authentication_token, owner: shop) 
    end 
end 

变化

trait :with_authentication_token do 
    before(:create) do |shop| 
    shop.authentication_token = build(:authentication_token, owner: shop) 
    end 
    after(:build) do |shop| 
    shop.authentication_token = build(:authentication_token, owner: shop) 
    end 
end 

我认为应该工作

+0

@chrishough你也应该upvote的答案,如果它帮助.. :) –

+1

@ArupRakshit是的,谢谢你的提醒 –