belongs_to :keeper, :class_name => "Staff"
belongs_to "staff", :foreign_key => "keeper_id"
In my basic tests, these seem to be doing the exact same thing.
Are they indeed the same?
Is one better than the other?
belongs_to :keeper, :class_name => "Staff"
belongs_to "staff", :foreign_key => "keeper_id"
In my basic tests, these seem to be doing the exact same thing.
Are they indeed the same?
Is one better than the other?
The two statements define the same association. The difference is how the defined associations are referenced by the class defining those associations.
Calling belongs_to defines a whole whack of new instance methods for the calling class to handle the given relation. These new methods are named based on the first argument of belongs_to. As with most of the rest of Rails, ActiveRecord will use sensible defaults derived from the first argument to generate the methods that manage the association. Providing additional arguments to belongs_to just override those defaults.
In reality, they are identical in all but name. It all comes down to your personal preference. Would you rather refer to the association with @model.keeper
or @model.staff
?
Have a read through the belongs_to section of the Associations reference to get a better idea of the methods provided when a model belongs to another and how the options to belongs_to are used.
No these statements are slightly different in the way they are going to give you methods on the class you are using them. Lets assume you are defining these statements inside the class Office, so the first statement, i.e.
class Office < ActiveRecord::Base
belongs_to :keeper, :class_name => "Staff"
end
is creating a relationship between Staff and Office class but the relationship from Office to Staff is called keeper and will use keeper_id as the foreign key in the Office class to establish the relationship. So if you have an instance of Office object in office variable then you can get the Staff for that office object using
office.keeper
In the other scenario,
class Office < ActiveRecord::Base
belongs_to :staff, :foreign_key => "keeper_id"
end
you are creating a relationship between Staff and Office class and the relationship from Office to Staff is called staff and will use keeper_id as the foreign key in the Office class to establish the relationship as you have specified the foreign key.
So in this case if you want to get to Staff, then you will do
office.staff
In summary, if you just do
belongs_to :staff
in your model, then according to rails convention, you will get a staff method in your model that will use staff_id as the foreign key to establish the relationship between the Staff model and this one. But rails also gives you the option to override these conventions in exceptional circumstances for instance, a legacy application. So basically you are overriding the rails convention in the above two statements by using the foreign key and class name.
Both codes do similar thing, but there is difference. In case of the first line, rails guesses that the reference to Staff
is done by keeper_id
, it just adds a _id
. In the second case you tell where it should search for the reference by giving the :foreign_key
attribute.
The difference may be in the way how you refer to the class you want to belong_to. In the first case it will be XY.keeper
, in the second it should be XY.staff
. Depends on you which form you prefer.
Although both methods are equivalent in terms of defining the relationship, with the primary difference being the name, the "better" of the two is the one you're currently using the most. It's a matter of consistency more than anything.
Do you want to refer to things as:
object.keeper
Or is it more sensible to use:
object.staff
My personal preference is for the first form, but generally to be clear I express all the quirks of the relationship if it is unusual in any regard. The definition would be:
belongs_to :keeper,
:class_name => 'Staff',
:foreign_key => :keeper_id
By spelling out the nature of the relationship in full, the amount of confusion that may arise is minimized.