Class: Shoulda::Matchers::ActiveRecord::AssociationMatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/shoulda/matchers/active_record/association_matcher.rb

Constant Summary collapse

MACROS =
{
  'belongs_to' => 'belong to',
  'has_many' => 'have many',
  'has_one' => 'have one',
  'has_and_belongs_to_many' => 'have and belong to many',
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(macro, name) ⇒ AssociationMatcher

Returns a new instance of AssociationMatcher.



1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1494

def initialize(macro, name)
  @macro = macro
  @name = name
  @options = {}
  @submatchers = []
  @missing = ''

  if macro == :belongs_to
    required(belongs_to_required_by_default?)
  end
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



1492
1493
1494
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1492

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



1492
1493
1494
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1492

def options
  @options
end

Instance Method Details

#autosave(autosave) ⇒ Object



1570
1571
1572
1573
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1570

def autosave(autosave)
  @options[:autosave] = autosave
  self
end

#class_name(class_name) ⇒ Object



1580
1581
1582
1583
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1580

def class_name(class_name)
  @options[:class_name] = class_name
  self
end

#conditions(conditions) ⇒ Object



1560
1561
1562
1563
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1560

def conditions(conditions)
  @options[:conditions] = conditions
  self
end

#counter_cache(counter_cache = true) ⇒ Object



1533
1534
1535
1536
1537
1538
1539
1540
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1533

def counter_cache(counter_cache = true)
  add_submatcher(
    AssociationMatchers::CounterCacheMatcher,
    counter_cache,
    name,
  )
  self
end

#dependent(dependent) ⇒ Object



1515
1516
1517
1518
1519
1520
1521
1522
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1515

def dependent(dependent)
  add_submatcher(
    AssociationMatchers::DependentMatcher,
    dependent,
    name,
  )
  self
end

#deprecated(deprecated = true) ⇒ Object



1645
1646
1647
1648
1649
1650
1651
1652
1653
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1645

def deprecated(deprecated = true)
  if Shoulda::Matchers::RailsShim.active_record_gte_8_1?
    @options[:deprecated] = deprecated
    self
  else
    raise NotImplementedError,
      '`deprecated` association matcher is only available on Active Record >= 8.1.'
  end
end

#descriptionObject



1660
1661
1662
1663
1664
1665
1666
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1660

def description
  description = "#{macro_description} #{name}"
  if options.key?(:class_name)
    description += " class_name => #{options[:class_name]}"
  end
  [description, submatchers.map(&:description)].flatten.join(' ')
end

#failure_messageObject



1668
1669
1670
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1668

def failure_message
  "Expected #{expectation} (#{missing_options})"
end

#failure_message_when_negatedObject



1672
1673
1674
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1672

def failure_message_when_negated
  "Did not expect #{expectation}"
end

#index_errors(index_errors) ⇒ Object



1575
1576
1577
1578
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1575

def index_errors(index_errors)
  @options[:index_errors] = index_errors
  self
end

#inverse_of(inverse_of) ⇒ Object



1542
1543
1544
1545
1546
1547
1548
1549
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1542

def inverse_of(inverse_of)
  add_submatcher(
    AssociationMatchers::InverseOfMatcher,
    inverse_of,
    name,
  )
  self
end

#join_table(join_table_name) ⇒ Object



1640
1641
1642
1643
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1640

def join_table(join_table_name)
  @options[:join_table_name] = join_table_name
  self
end

#join_table_nameObject



1699
1700
1701
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1699

def join_table_name
  options[:join_table_name] || reflector.join_table_name
end

#matches?(subject) ⇒ Boolean

Returns:

  • (Boolean)


1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1676

def matches?(subject)
  @subject = subject
  association_exists? &&
    macro_correct? &&
    validate_inverse_of_through_association &&
    (polymorphic? || class_exists?) &&
    foreign_type_matches? &&
    foreign_key_exists? &&
    primary_key_exists? &&
    query_constraints_exists? &&
    class_name_correct? &&
    join_table_correct? &&
    autosave_correct? &&
    index_errors_correct? &&
    conditions_correct? &&
    validate_correct? &&
    touch_correct? &&
    types_correct? &&
    strict_loading_correct? &&
    deprecated_correct? &&
    submatchers_match?
end

#option_verifierObject



1703
1704
1705
1706
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1703

def option_verifier
  @_option_verifier ||=
    AssociationMatchers::OptionVerifier.new(reflector)
end

#optional(optional = true) ⇒ Object



1615
1616
1617
1618
1619
1620
1621
1622
1623
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1615

def optional(optional = true)
  remove_submatcher(AssociationMatchers::RequiredMatcher)
  add_submatcher(
    AssociationMatchers::OptionalMatcher,
    name,
    optional,
  )
  self
end

#order(order) ⇒ Object



1524
1525
1526
1527
1528
1529
1530
1531
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1524

def order(order)
  add_submatcher(
    AssociationMatchers::OrderMatcher,
    order,
    name,
  )
  self
end

#required(required = true) ⇒ Object



1605
1606
1607
1608
1609
1610
1611
1612
1613
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1605

def required(required = true)
  remove_submatcher(AssociationMatchers::OptionalMatcher)
  add_submatcher(
    AssociationMatchers::RequiredMatcher,
    name,
    required,
  )
  self
end

#source(source) ⇒ Object



1551
1552
1553
1554
1555
1556
1557
1558
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1551

def source(source)
  add_submatcher(
    AssociationMatchers::SourceMatcher,
    source,
    name,
  )
  self
end

#strict_loading(strict_loading = true) ⇒ Object



1635
1636
1637
1638
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1635

def strict_loading(strict_loading = true)
  @options[:strict_loading] = strict_loading
  self
end

#through(through) ⇒ Object



1506
1507
1508
1509
1510
1511
1512
1513
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1506

def through(through)
  add_submatcher(
    AssociationMatchers::ThroughMatcher,
    through,
    name,
  )
  self
end

#touch(touch = true) ⇒ Object



1630
1631
1632
1633
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1630

def touch(touch = true)
  @options[:touch] = touch
  self
end

#types(types) ⇒ Object



1565
1566
1567
1568
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1565

def types(types)
  @options[:types] = types
  self
end

#validate(validate = true) ⇒ Object



1625
1626
1627
1628
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1625

def validate(validate = true)
  @options[:validate] = validate
  self
end

#with_foreign_key(foreign_key) ⇒ Object



1585
1586
1587
1588
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1585

def with_foreign_key(foreign_key)
  @options[:foreign_key] = foreign_key
  self
end

#with_foreign_type(foreign_type) ⇒ Object



1590
1591
1592
1593
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1590

def with_foreign_type(foreign_type)
  @options[:foreign_type] = foreign_type
  self
end

#with_primary_key(primary_key) ⇒ Object



1595
1596
1597
1598
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1595

def with_primary_key(primary_key)
  @options[:primary_key] = primary_key
  self
end

#with_query_constraints(query_constraints) ⇒ Object



1600
1601
1602
1603
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1600

def with_query_constraints(query_constraints)
  @options[:query_constraints] = query_constraints
  self
end

#without_validating_presenceObject



1655
1656
1657
1658
# File 'lib/shoulda/matchers/active_record/association_matcher.rb', line 1655

def without_validating_presence
  remove_submatcher(AssociationMatchers::RequiredMatcher)
  self
end