Search code examples
ruby-on-rails-4mongoid4

Mongoid/Rails has_and_belongs_to_many returning true in loop - why?


I've got two models (product and category):

class Product

    include Mongoid::Document
    include Mongoid::Timestamps

    field :name,            type: String
    field :enabled,         type: Boolean
    field :price,           type: BigDecimal
    field :sku,             type: String
    field :editing,         type: Boolean
    field :supplier,        type: String

    has_and_belongs_to_many             :categories
    has_and_belongs_to_many             :subcategories

    validates :name, presence: true, uniqueness: true
    validates :price, presence: true

end

class Category

    include Mongoid::Document
    include Mongoid::Timestamps

    field :name,            type: String
    field :editing,         type: Boolean
    field :enabled,         type: Boolean

    has_and_belongs_to_many             :subcategories
    has_and_belongs_to_many             :products

    validates :name, presence: true, uniqueness: true

end

As you can see both have the has_and_belongs_to_many relationship. All works as expected whilst saving/retrieving data:

@products = Products.all

which will return this json:

{
    _id: ObjectId("54ba495957694d4d95010000"),
    category_ids: [
        ObjectId("54ba494557694d4d95000000")
    ],
    created_at: ISODate("2015-01-17T11:36:57.641Z"),
    enabled: false,
    name: "Product 1",
    price: "23.9",
    sku: "KOPP0909",
    updated_at: ISODate("2015-01-17T11:36:57.641Z")
}

So far so good. In my view I'll loop through the products like so:

@products.each do |p|
    p.categories.each do |c|
        c.name
        ...

Which will return display the category name as expected. The issue I'm having is while the above code will return the category(ies) as expected it'll also print true at the end of it (in case of the object above):

Category 1 and true

What is that? How can I remove it?


Solution

  • As @phoet said, the pseudo code stops us from knowing exactly what is happening, but I'm going to guess that you're doing something as simple as outputting the value of your loop rather than silently looping and outputting only the categories. For example, note the equal sign in the following examples, which would output some value of the object itself, in addition to the nested output:

    In ERB:

    <%= for @products.each do |p| %>
      <%= p.categories.each do |c| %>
        <%= c.name %>
      <% end %>
    <% end %>
    

    vs

    <% for @products.each do |p| %>
      <% p.categories.each do |c| %>
        <%= c.name %>
      <% end %>
    <% end %>
    

    In HAML:

    = for @products.each do |p|
      = p.categories.each do |c|
        = c.name
    

    vs

    - for @products.each do |p|
      - p.categories.each do |c|
        = c.name