Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to alias a belongs_to association in Rails?

I have a model with a belongs_to association:

class Car < ActiveRecord::Base
  belongs_to :vendor
end

So I can call car.vendor. But I also want to call car.company! So, I have the following:

class Car < ActiveRecord::Base
  belongs_to :vendor
  def company
    vendor
  end
end

but that doesn't solve the assignment situation car.company = 'ford', so I need to create another method for that. Is there a simple alias mechanism I can use for associations? Can I just use alias_method :company, :vendor and alias_method :company=, :vendor=?

like image 512
at. Avatar asked Jan 31 '14 01:01

at.


People also ask

What are associations in Rails?

Association in Rails defines the relationship between models. It is also the connection between two Active Record models. To figure out the relationship between models, we have to determine the types of relationship. Whether it; belongs_to, has_many, has_one, has_one:through, has_and_belongs_to_many.


3 Answers

No it doesn't look for company_id for instance change your code as follows

In Rails3

class Car < ActiveRecord::Base
   belongs_to :vendor
   belongs_to :company, :class_name => :Vendor,:foreign_key => "vendor_id"
end

In Rails4

We can use alias attribute.

alias_attribute :company, :vendor
like image 128
pramod Avatar answered Oct 28 '22 01:10

pramod


In Rails 4, you should simply be able to add alias_attribute :company, :vendor to your model.

like image 32
Fran Worley Avatar answered Oct 28 '22 02:10

Fran Worley


Short Version:

  1. Generate model with migration

    $ rails generate model Car vendor:references name:string ...

  2. Add following line in Car model i.e car.rb file

    class Car < ActiveRecord::Base
      belongs_to :company, :class_name => 'Vendor', :foreign_key => 'vendor_id'
    end
    
  3. Now you have @car.company instance method.

For a Detailed explanation read ahead [Optional if you understood the above !!]

Detailed Version:

The model Car will have an association with the model Vendor (which is obvious). So there should be a vendor_id in the table cars.

  1. In order to make sure that the field vendor_id is present in the cars table run the following on the command line. This will generate the right migration. The vendor:references is important. You can have any number of attributes after that.

    $ rails generate model Car vendor:references name:string

  2. Or else in the existing migration for create_table :cars just add the line t.references :vendor

    class CreateCars < ActiveRecord::Migration
      def change
        create_table :cars do |t|
          t.string :name
          ...
          t.references :vendor
          t.timestamps
        end
      end
    end
    
  3. The final thing that you need to do is edit the model Car. So add this code to your car.rb file

    class Car < ActiveRecord::Base
      belongs_to :company, :class_name => 'Vendor', :foreign_key => 'vendor_id'
    end
    

After you do the third step you will get the following instance methods for the model Car provided by Rails Associations

  1. @car.company

    • When you do @car.company it will return a #<Vendor ...> object. To find that #<Vendor ...> object it will go look for the vendor_id column in the cars table because you have mentioned :foreign_key => 'vendor_id'

    • You can set the company for a car instance by writing

      @car.company = @vendor || Vendor.find(params[:id]) #whichever Vendor object you want
      @car.save
      

      This will save the id of that Vendor object in the vendor_id field of the cars table.

Thank You.

like image 13
Vishal S Mujumdar Avatar answered Oct 28 '22 03:10

Vishal S Mujumdar