Possible to alias a belongs_to association in Rails?
Solution 1
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
Solution 2
In Rails 4, you should simply be able to add alias_attribute :company, :vendor
to your model.
Solution 3
Short Version:
Generate model with migration
$ rails generate model Car vendor:references name:string ...
Add following line in
Car
model i.ecar.rb
fileclass Car < ActiveRecord::Base belongs_to :company, :class_name => 'Vendor', :foreign_key => 'vendor_id' end
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
.
In order to make sure that the field
vendor_id
is present in thecars
table run the following on the command line. This will generate the right migration. Thevendor:references
is important. You can have any number of attributes after that.$ rails generate model Car vendor:references name:string
Or else in the existing migration for
create_table :cars
just add the linet.references :vendor
class CreateCars < ActiveRecord::Migration def change create_table :cars do |t| t.string :name ... t.references :vendor t.timestamps end end end
The final thing that you need to do is edit the model
Car
. So add this code to yourcar.rb
fileclass 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
@car.company
When you do
@car.company
it will return a#<Vendor ...>
object. To find that#<Vendor ...>
object it will go look for thevendor_id
column in thecars
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 thatVendor
object in thevendor_id
field of thecars
table.
Thank You.
Solution 4
class Car < ActiveRecord::Base
belongs_to :vendor
belongs_to :company, :class_name => :Vendor
end
at.
Updated on May 31, 2020Comments
-
at. almost 4 years
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 callcar.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 simplealias
mechanism I can use for associations? Can I just usealias_method :company, :vendor
andalias_method :company=, :vendor=
? -
at. over 10 yearswouldn't this look for a
company_id
field in the database? -
Hilder Vitor Lima Pereira almost 9 yearsGood tip! Just to point: using
alias_attribute
makes still possible to access both the attributescompany
andvendor
, while using only the relationbelongs_to :company, :class_name => :Vendor,:foreign_key => "vendor_id"
hides the attributevendor
. -
wes.hysell about 8 yearsNo, at least in Rails 4.2. After some testing, it appears that the column name is determined by the class used, not the association's attribute name. So
belongs_to :company, class_name: :Vendor
would search for a column in your table namedvendor_id
- whereas not specifying the class_name option will auto-resolve to use class nameCompany
and would search for acompany_id
column. Nevertheless, it still may be considered better practice to supply theforeign_key:
option to help eliminate future headaches. -
Will I AM almost 8 yearsUnfortunately reflect_on_association doesn't work with the latter.
-
Jerome over 7 yearsThe rails 4 syntax is concise, but works if your syntax is picture perfect. By doing
belongs_to :company, class_name: :Vendor, foreign_key: "vendor_id"
you actually have a better handle on the syntax of your variables and can use that as an intermediary step to "succincty'