Search code examples
ruby-on-railsunit-testingfixtureshas-and-belongs-to-manysingle-table-inheritance

Rails Single Table Inheritance with HABTM Fixture in unit testing returning NoMethodError: undefined method `singularize'


Imagine a model structure as follows:

models/cross_sell_promotion.rb

     class CrossSellPromotion < Promotion
       has_and_belongs_to_many :afflicted_products, :join_table => :promotion_afflicted_products, :foreign_key => 'promotion_id', :association_foreign_key => 'product_id', :class_name => 'Product'
       has_and_belongs_to_many :afflicted_categories, :join_table => :promotion_afflicted_categories, :foreign_key => 'promotion_id', :association_foreign_key => 'category_id', :class_name => 'Category'
       . . .
     end

models/promotion.rb

class Promotion < ActiveRecord::Base
  has_and_belongs_to_many :products, :join_table => :promotions_products
  has_and_belongs_to_many :categories, :join_table => :promotions_categories
  - - -
end

and tables as follows:

table promotions
type :string
...some other fields unrelated to this problem

table promotions_products
promotion_id :integer
product_id :integer

table promotion_afflicted_products
promotion_id :integer
product_id :integer

table promotion_afflicted_categories
promotion_id :integer
category_id :integer

Then I have a fixtures as follows:

#promotions.yml
cross_sell_1:
products: plumeboom_1, plumeboom_2
  value: 100
  value_type: percentage
  type: CrossSellPromotion

#products.yml
plumeboom_1:
  model: plumeboom1
  url: plumeboom-1

plumeboom_2:
  model: plumeboom2
  url: plumeboom-2

plumeboom_3:
  model: plumeboom3
  url: plumeboom-3

When I run my unit test, it returns this error message:

1) Error:
test_the_truth(CartTest):
NoMethodError: undefined method `singularize' for :promotions_products:Symbol

Please, let me know if you happen to have similar experience or know how to fix this, or at least just what you thought might be wrong, I am ready to try anything out!

Thanks a lot, please do not hesitate to reply... really desperate here!


Solution

  • The answer is... You can't!

    Sadly but sometimes Rails just won't cut it. In these situations just create another Fixture for association tables.

    E.g. in this case promotions_products.yml and inside it you enter:

    pp1:
        promotion_id: <%= Fixtures.identify(:cross_sell_1) %>
        product_id: <%= Fixtures.identify(:plumeboom_1) %>
    

    I managed to use HABTM connections in fixtures but when they are also having STI (single table inheritance) rails seems to have problems with it.