referencing attributes in models with belongs_to relationships through a nested namespace

Scott picture Scott · Jan 4, 2011 · Viewed 7.6k times · Source

Ok, so I thought I understood how the relationship specifications work in rails but I've been struggling with this for a day now.

Some context, I have two models Cars & Model Names (e.g. Impala, Charger, etc), where Cars are instances of Model Names, and Model Names really is nothing more than a lookup table of Model Names and some other model level attributes. The Model Name controller is nested within the admin namespace as only admins can CRUD Model Names. End users can add instances of cars to the Cars model.

So, in routes.rb I have:

  resources :cars

  namespace :admin do resources :model_names end

The Model's are defined as:

class Admin::ModelName < ActiveRecord::Base
end
class Car < ActiveRecord::Base
  belongs_to :admin_model_name
end

The Migrations are:

class CreateCars < ActiveRecord::Migration
  def self.up
    create_table :cars do |t|
      t.string :chassis_number
      t.string :description
      t.references :admin_model_name
      t.timestamps
   end
end

class CreateAdminModelNames < ActiveRecord::Migration
  def self.up
    create_table :admin_model_names do |t|
      t.string :model
      t.integer :sort_index
      #...additional attributes removed
      t.timestamps
    end

The admin CRUD of ModelName all work great. The problem is in the Car views. I think I should be referencing a particular cars model name like such:

<%= @car.admin_model_names.Model =>

But I get the error:

undefined method `admin_model_names' for #<Car:0x000001040e2478>

I've tried the attr_accessible on the ModelNames model but to no avail. The underlying data is referenced correctly. I have also have HABTMT relationship between Cars & Users and that all worked fine referencing each others attributes from the different entities views. But haven't been able to get this to work. Is it due to the nested resource & admin control inheritance?

The only referencing method I found that works is:

 <%= Admin::ModelName.find(@car.admin_model_name_id).model %>

But this really seems to be too much code (and expense of a find) to get to that attribute. Is there a Rails way?

Thanks in advance.

Scott

Answer

guapolo picture guapolo · Dec 19, 2011

Have you tried:

class Car < ActiveRecord::Base   
  belongs_to :admin_model_name, :class_name => "Admin::ModelName" 
end

as stated in

http://guides.rubyonrails.org/association_basics.html

section 3.4?

you may also need to set the

:foreign_key => "admin_model_name_id"
attribute to specify the referencing model.

Hope it helps.