1

I'm building a site on Refinery CMS, and have generated two extensions: one for Brands, and another for Bicycle Types (it's a site for a bike shop).

Now, what I want to do is have the Brands extension handle the creation of brand pages, which will be pulled into a brand index. On this page, I want to be able to filter by Bicycle Type, which is where the second extension comes in. Through the Bicycle Type extension, you can create a bicycle type, which I want to associate to a Brand. A Brand can have multiple Bicycle Types, and vice versa.

So, I edited the Brands model to add has_and_belongs_to_many :bicycle_types, and the Bicycle Types model to include has_and_belongs_to_many :brands and accepts_nested_attributes_for :brands. I wrote a migration to create a join table, and everything was going well so far.

I then went to modify the form for the Brands extension, and got my checkboxes displaying correctly and seemingly generating the right code. However, the problem occurs when I come to submit the form - I get NameError in Refinery::Brands::Admin::BrandsController#update and uninitialized constant Refinery::Brands::Brand::BicycleType.

The parameters I get look like the bicycle type IDs are being passed through correctly:

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"3193ZMPXkmHdgZThXwAurD6xF2eZ533Tb71pAi7Jxbs=",
 "switch_locale"=>"en",
 "brand"=>{"title"=>"Cannondale",
 "teaser"=>"",
 "splash"=>"",
 "details"=>"",
 "introduction"=>"",
 "blockquote"=>"",
 "bicycle_type_ids"=>["1",
 "2"],
 "logo_id"=>"",
 "teaser_image_id"=>"",
 "splash_image_id"=>""},
 "id"=>"2",
 "locale"=>:en}

I've been trying to figure this out and just keep hitting the same brick wall, so any help would be greatly appreciated!

Here's my code. Let me know if anything else would help.

Brands Controller

module Refinery
  module Brands
    module Admin
      class BrandsController < ::Refinery::AdminController

        crudify :'refinery/brands/brand',
                :xhr_paging => true

      end
    end
  end
end

Brands Model

module Refinery
  module Brands
    class Brand < Refinery::Core::BaseModel
      self.table_name = 'refinery_brands'

      attr_accessible :title, :teaser, :splash, :details, :introduction, :blockquote, :logo_id, :teaser_image_id, :splash_image_id, :position, :bicycle_type_ids

      translates :title, :teaser, :splash, :details, :introduction, :blockquote

      class Translation
        attr_accessible :locale
      end

      validates :title, :presence => true, :uniqueness => true

      belongs_to :logo, :class_name => '::Refinery::Image'

      belongs_to :teaser_image, :class_name => '::Refinery::Image'

      belongs_to :splash_image, :class_name => '::Refinery::Image'

      has_and_belongs_to_many :bicycle_types
    end
  end
end

Bicycle Types Model

module Refinery
  module BicycleTypes
    class BicycleType < Refinery::Core::BaseModel
      self.table_name = 'refinery_bicycle_types'

      attr_accessible :title, :position

      translates :title

      class Translation
        attr_accessible :locale
      end

      validates :title, :presence => true, :uniqueness => true

      has_and_belongs_to_many :brands
      accepts_nested_attributes_for :brands
    end
  end
end

Migration

class AddRefineryBicycleTypesBrands < ActiveRecord::Migration
  def change
    create_table :bicycle_types_brands, :id => false do |t|
      t.references :bicycle_type
      t.references :brand
    end
    add_index :bicycle_types_brands, [:bicycle_type_id, :brand_id], :unique => true
  end
end

Form Partial (at least the part where I'm building my checkboxes)

<div class="field">
  <%= f.label :bicycle_types %>
    <% Refinery::BicycleTypes::BicycleType.order(:title).each do |bicycle_type| %>
      <label class="checkbox">
        <%= check_box_tag "#{f.object_name}[bicycle_type_ids][]", bicycle_type.id, f.object.bicycle_types %>
      <%= bicycle_type.title %>
    </label>
  <% end %>
</div>

If the rest of the partial would be useful, or anything else for that matter, please let me know. Any help would be greatly appreciated!

digisquid
  • 11
  • 2

1 Answers1

2

you must specify the full class name:

has_and_belongs_to_many :bicycle_types, :class_name => "Refinery::BicycleTypes::BicycleType"

This is not your case but if you want to call the join table in a 'refinery style' (i.e refinery_bicycle_types_brands), you must also declare the join table:

has_and_belongs_to_many :bicycle_types, :join_table => :refinery_bicycle_types_brands, :class_name => "Refinery::BicycleTypes::BicycleType"

Bye

David71
  • 51
  • 3