conflict between attribute name and foreign key name - ruby-on-rails

I am wondering if it is possible to have the following situation: I have a person object that has both an attribute called email and a foreign key called email which is realized as a has_many relationship. The latter is supposed to contain not only the primary email but also secondary ones. Would this cause conflict when I invoke #person.email? What would be the standard way to work around this? Thanks.

Create a secound field that could be used as a foreign key and then in the associated model add :foreign_key => 'your_foreign_key' as aparameter to the existing association like this:
has_many :email_addresses, :class_name => 'ClassName', :foreign_key => 'your_foreign_key'
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html <-- Documentation about that.

Related

Rails association primary_key option

I understand that foreign keys are for specifying when you have a different column name (different than parent child's class name) on the child class. I know what primary keys and foreign keys are and have read the rails documentation on associations several times, but I can't figure out what the primary key option is for.
1) But what is the primary_key option for? How does it change the sql when an association is called?
2) In what instances would you need to specify the primary_key on association?
3) In what instances would you need to specify both the primary_key and foreign_key?
below is an example of specifying the foreign_key option on associations:
class User
has_many :texts, foreign_key: :owner_id
end
class Text
belongs_to :user, foreign_key: :owner_id
end
User Table
id| name |
Text Table
id| owner_id |name
Ok so I thought more about the SQL and figured it out. You use foreign_key option when your child has a different foreign_key name then your parent's classname_id BUT on your parent table, you are still using ID as your identifier.
user table
id|name|age
text table
id|random_id|conversations
select * from user where user.id = text.random_id
select * from text where text.random_id (foreign_key) = account.id (primary key)
On the other hand, you use primary_key with foreign_key when you don't want to use id at all to link the relationship.
user table
id|userable_id|name|age
text table
id|userable_ss_id|conversations
HERE: if you wanted to link the userable_ss_id to userable_id, you would include both primary_key and foreign_key options on both relationships.
class User
has_many :texts, primary_key: :userable_ss_id, foreign_key: :userable_id
end
class Text
belongs_to :user, primary_key: :userable_ss_id, foreign_key: :userable_id
end
Basic rule of thumb:
select * from text where text.(foreign_key) = account.(primary key)
primary key concerns the main table and foreign key the associated one
U 've used the foreign key correctly. If for isntance User had another primary key than :id u'd have to specify that either.
#User
has_many :texts, primary_key: :uuid, foreign_key: owner_id
So you need this options, if you want to have another naming of the keys than rails conventions assume for the main and associated table respectivly
Rails uses convention over configuration.
By convention, all database tables in rails have a primary-key of the id column.
If, for some odd reason (eg you've got a legacy database), your table uses a different primary key to id... you use the primary_key call to tell rails what it is.
By convention, all associations use a foreign-key of <model>_id for the foreign key.
If, for some reason, your association uses a different foreign-key to find the associated model - you'd use foreign_key to tell rails what it is.
Unlike primary_key, using foreign_key can be much more common. Especially when you have more than one association using the same table but with different association names.

Rails foreign key other than id

I have an ActiveRecord named Ad, and it has column id and server_id. They are both unique. id is given by Rails, but what's meaningful here is server_id.
Then I need to create another ActiveRecord named Bid which has 1 to 1 relationship with Ad. Bid has a key ad_id which refers to Ad.server_id.
I know that I should specify Ad has_one Bid and Bid belongs_to Ad, and specify foreign key name through foreign_key: "ad_id". What's troubling me here is I can only find out how to let Bid.ad_id refer to Ad.id while I want it refers to Ad.server_id.
Can anybody show me how to achieve this? Thanks!
User primary key
Bid.rb
belongs_to :ad, :foreign_key => :ad_id, :primary_key => :server_id
Ad.rb
has_one :bid, :foreign_key => :ad_id, :primary_key => :server_id
foregin_key option is not needed here but adding to make the difference between it and primary_key clear.
Have you tried using 'references' when generating your model.
i.e.
rails generate model Advertisement bid:references

Rails belongs_to returns nil class

I am trying to link two tables to each other
class Musers < ActiveRecord::Base
# Email
# sid (student_id:integer)
# isyk: boolean
belongs_to :user, :foreign_key => "smail"
end
class Users < ActiveRecord::Base
belongs_to :muser, :foreign_key => "email"
end
But,
#user = Users.first
#user.muser returns nil
By saying :foreign_key => "smail" you are telling rails that the Muser column smail points to the User model's foreign key. This is most likely not the case.
Assuming that the primary key of the User models is called id, you should a user_id field to Muser, and change belongs_to :user, :foreign_key => "smail" into:
belongs_to :user
On the User model you can define the reverse relation using:
has_one :muser
Also, to follow rails model naming conventions, you should rename Users to User and Musers to Muser.
You should read more about belongs_to and has_one.
If, on the other hand, the User model in fact uses email for it's primary key, I would strongly advise you to change that and add an auto-incrementing primary key instead. As a rule of thumb, the primary key should be chosen such that it never changes. If it does change, all foreign keys pointing to that primary key will have to change as well.
You should only use a non auto-incrementing primary key if you have a specific reason for doing so.
More information on choosing a primary key: How to choose my primary key?
Well you can't just tell rails the type of association, you actually have to set the association to an instance of that class. For example, making a new muser will not automatically assign a user as the belongs_to. You could do something like
u = User.new
u.muser = Muser.first
u.save
However, I'm not sure what you are trying to accomplish with a belongs_to - belongs_to relationship, but you should know that you have to do more than just tell rails it exists.

ActiveRecord belongs_to reverse mapping. Getting symbol associated with foreign key

I have a model say Issue(ActiveRecord)
it has some fields viz. priority_id, status
:status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
is there a way to know at run time- a field belongs to what model?
in above example, how to know the symbol associated with :foreign_key => 'status_id'
for instance, i want to get :status and i have 'status_id' at run time
comments please.
thanks
You can always use issue.status.class to show the class of the status field (where issue is an object of the Issue model), Note that this is not specific to ActiveRecord, you can call the class method on any object to find it's class/type.

Foreign key same as associated table?

i have a cutom foreign key name (non association+_id) like so:
belongs_to :investment_advisor, :foreign_key => "investment_advisor"
This creates a problem because rails gets confused and doesnt know if im referring to the association or the foreign key. Is there any way i can rename the foreign key (without touching the database) to something else? Like a variable or something?
You could rename your association, for one:
belongs_to :investment_advisor_obj,
:foreign_key => "investment_advisor",
:class_name => "InvestmentAdvisor"
(or you could pick a less silly name)

Resources