Reputation: 20222
I have a class Prediction
which belongs_to
either a currency
or a market
.
belongs_to :market
belongs_to :currency
validate :market_xor_currency?, on: [:new, :create, :edit, :update]
def market_xor_currency?
if(self.market != nil && self.currency != nil)
false
end
true
end
I am testing with Rspec in this manner:
p1 = FactoryGirl.create(:prediction)
p1.currency = FactoryGirl.create(:currency)
expect{ p1.market = FactoryGirl.create(:market) }.to raise_error
However, the test fails. How can I make Prediction
belong to either a currency
or a market
?
Upvotes: 1
Views: 182
Reputation: 26
I believe something like this should work in your case:
class MyValidator < ActiveModel::Validator
def validate(record)
if(record.market != nil && record.currency != nil)
record.errors[:name] << 'market xor currency'
end
end
end
class SomeModel < ActiveRecord::Base
include ActiveModel::Validations
validates_with MyValidator
end
Upvotes: 0
Reputation: 42799
I think a polymorphic relation is more suitable for a such relation
class Market < ActiveRecord::Base
has_many :predictions, as: :predictable
end
class Currency < ActiveRecord::Base
has_many :predictions, as: :predictable
end
class Prediction < ActiveRecord::Base
belongs_to :predictable, polymorphic: true
end
This way you won't need to validate any thing, because by definition the prediction can only belong to either one of them
More about polymorphic relations
if you still want to do it your way, then I think this validation method should work
def market_xor_currency?
unless market.nil? ^ currency.nil?
errors.add(:base, 'whatever error you want')
end
end
Upvotes: 2
Reputation: 1963
In order to make custom method validation, you need to add error if not valid:
http://guides.rubyonrails.org/active_record_validations.html#custom-methods
Upvotes: 0