0

Ich habe eine ziemlich direkte Poly-Association-Setup. Ich versuche zu validieren, dass Tokens nur bei Anbietern oder Shops existieren, nicht bei beiden. Diese Validierungen funktionieren korrekt, wenn ich "hacken" benutze, aber mein Refaktor hat die Fabriken durchgebrannt.Factorygirl mit polymorphen Assoziationen und akzeptierten geschachtelten Attributen fehlschlägt Validierungen

Problem

Wenn Sie das Geschäft mit einem Token heißt FactoryGirl.create erstellen (: shop,: with_authentication_token) bläst, weil das Geschäft nicht angelegt bekommen und gespeichert wie FG versucht, es zu verarbeiten? Kann mir jemand in die richtige Richtung zeigen, um die Ladenfabrik einzurichten?

Fehler

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

Momentan befindet sich der Anbieter Fabrik funktioniert, weil es die Eltern ist.

Arbeiten in PRY?

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

Tabelle

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 

Fabriken

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 

Modelle

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 

Antwort

3

so können Sie keinen Trigger auf beiden Modell speichern, bevor das zugehörige Modell instanziiert wird und im Zusammenhang

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 

Änderung

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 

denke ich, dass

+0

@chrishough Sie arbeiten sollten sollte auch die Antwort upvote, wenn es geholfen hat .. :) –

+1

@ArupRakshit yep, danke für die Erinnerung –

Verwandte Themen