class Shoulda::ActiveRecord::Matchers::AssociationMatcher
:nodoc:
def associated_class
def associated_class reflection.klass end
def association_exists?
def association_exists? if reflection.nil? @missing = "no association called #{@name}" false else true end end
def belongs_foreign_key_missing?
def belongs_foreign_key_missing? @macro == :belongs_to && !class_has_foreign_key?(model_class) end
def class_has_foreign_key?(klass)
def class_has_foreign_key?(klass) if klass.column_names.include?(foreign_key.to_s) true else @missing = "#{klass} does not have a #{foreign_key} foreign key." false end end
def dependent(dependent)
def dependent(dependent) @dependent = dependent self end
def dependent_correct?
def dependent_correct? if @dependent.nil? || @dependent.to_s == reflection.options[:dependent].to_s true else @missing = "#{@name} should have #{@dependent} dependency" false end end
def description
def description description = "#{macro_description} #{@name}" description += " through #{@through}" if @through description += " dependent => #{@dependent}" if @dependent description end
def expectation
def expectation "#{model_class.name} to have a #{@macro} association called #{@name}" end
def failure_message
def failure_message "Expected #{expectation} (#{@missing})" end
def foreign_key
def foreign_key reflection.primary_key_name end
def foreign_key_exists?
def foreign_key_exists? !(belongs_foreign_key_missing? || has_foreign_key_missing?) end
def has_foreign_key_missing?
def has_foreign_key_missing? [:has_many, :has_one].include?(@macro) && !through? && !class_has_foreign_key?(associated_class) end
def initialize(macro, name)
def initialize(macro, name) @macro = macro @name = name end
def join_table
def join_table reflection.options[:join_table] end
def join_table_exists?
def join_table_exists? if @macro != :has_and_belongs_to_many || ::ActiveRecord::Base.connection.tables.include?(join_table.to_s) true else @missing = "join table #{join_table} doesn't exist" false end end
def macro_correct?
def macro_correct? if reflection.macro == @macro true else @missing = "actual association type was #{reflection.macro}" false end end
def macro_description
def macro_description case @macro.to_s when 'belongs_to' then 'belong to' when 'has_many' then 'have many' when 'has_one' then 'have one' when 'has_and_belongs_to_many' then 'have and belong to many' end end
def matches?(subject)
def matches?(subject) @subject = subject association_exists? && macro_correct? && foreign_key_exists? && through_association_valid? && dependent_correct? && join_table_exists? end
def model_class
def model_class @subject.class end
def negative_failure_message
def negative_failure_message "Did not expect #{expectation}" end
def reflection
def reflection @reflection ||= model_class.reflect_on_association(@name) end
def through(through)
def through(through) @through = through self end
def through?
def through? reflection.options[:through] end
def through_association_correct?
def through_association_correct? if @through == reflection.options[:through] "Expected #{model_class.name} to have #{@name} through #{@through}, " << " but got it through #{reflection.options[:through]}" true else false end end
def through_association_exists?
def through_association_exists? if through_reflection.nil? "#{model_class.name} does not have any relationship to #{@through}" false else true end end
def through_association_valid?
def through_association_valid? @through.nil? || (through_association_exists? && through_association_correct?) end
def through_reflection
def through_reflection @through_reflection ||= model_class.reflect_on_association(@through) end