Hi,
suppose I''m doing a rails system for the DMV.
The rules say:
A person may have 0 or 1 Drivers License.
So, I''d have these 2 tables:
class CreatePeople < ActiveRecord::Migration
  def self.up
    create_table :people do |t|
      t.column :name, :string
    end
  end
  def self.down
    drop_table :people
  end
end
class CreateDriverslicenses < ActiveRecord::Migration
  def self.up
    create_table :driverslicenses do |t|
      t.column :person_id, :integer
    end
  end
  def self.down
    drop_table :driverslicenses
  end
end
And these models:
class Person < ActiveRecord::Base
  has_one :driverslicense
end
class DriversLicense < ActiveRecord::Base
  belongs_to :person
end
What is the best way to enforce this rule:
A person may have 0 or 1 Drivers License.
??
I ran a simple test with console:
>> pete = Person.new
=> #<Person:0x2364d9c @attributes={"name"=>nil},
@new_record=true>>> pete.name = ''Pete''
=> "Pete"
>> dl1 = Driverslicense.new
=> #<Driverslicense:0x235ac0c @attributes={"person_id"=>nil},
@new_record=true>
>> dl1.person_id = pete
=> #<Person:0x2364d9c @errors=#<ActiveRecord::Errors:0x23511ac
@errors={}, @base=#<Person:0x2364d9c ...>>,
@attributes={"name"=>"Pete", "id"=>1},
@new_record=false>
>> dl1.person.name
=> "Pete"
So, now Pete has a drivers license.
Let''s try to give him another drivers license:
>> dl2 = Driverslicense.new
=> #<Driverslicense:0x233de2c @attributes={"person_id"=>nil},
@new_record=true>>> dl2.person_id = pete
=> #<Person:0x2364d9c @errors=#<ActiveRecord::Errors:0x23511ac
@errors={}, @base=#<Person:0x2364d9c ...>>,
@attributes={"name"=>"Pete", "id"=>1},
@new_record=false>>>
>> dl2.person.name
=> "Pete">>
It appears that dmv has assigned 2 drivers licenses to Pete.
Is it up to me to ''strengthen'' the has_one() method in AR?
Here is info about my rails:
$ script/about
About your application''s environment
Ruby version                 1.8.4 (powerpc-darwin7.9.0)
RubyGems version             0.9.0
Rails version                1.1.6
Active Record version        1.14.4
Action Pack version          1.12.5
Action Web Service version   1.1.6
Action Mailer version        1.2.5
Active Support version       1.3.1
-Pete
http://GoodJobFastCar.com
goodjobfastcar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
--~--~---------~--~----~------------~-------~--~----~
 You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
You could add a uniqueness validation on the Driverslicense model class Driverslicense < ActiveRecord::Base validates_uniqueness_of :person_id end -Jonathan. On 11/18/06, Peter Smith [gjfc] <goodjobfastcar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > Hi, > > suppose I''m doing a rails system for the DMV. > > The rules say: > > A person may have 0 or 1 Drivers License. > > So, I''d have these 2 tables: > > class CreatePeople < ActiveRecord::Migration > def self.up > create_table :people do |t| > t.column :name, :string > end > end > > def self.down > drop_table :people > end > end > > class CreateDriverslicenses < ActiveRecord::Migration > def self.up > create_table :driverslicenses do |t| > t.column :person_id, :integer > end > end > > def self.down > drop_table :driverslicenses > end > end > > And these models: > > class Person < ActiveRecord::Base > has_one :driverslicense > end > > class DriversLicense < ActiveRecord::Base > belongs_to :person > end > > What is the best way to enforce this rule: > > A person may have 0 or 1 Drivers License. > ?? > > I ran a simple test with console: > > >> pete = Person.new > => #<Person:0x2364d9c @attributes={"name"=>nil}, @new_record=true> > >> pete.name = ''Pete'' > => "Pete" > > > >> dl1 = Driverslicense.new > => #<Driverslicense:0x235ac0c @attributes={"person_id"=>nil}, > @new_record=true> > > >> dl1.person_id = pete > => #<Person:0x2364d9c @errors=#<ActiveRecord::Errors:0x23511ac > @errors={}, @base=#<Person:0x2364d9c ...>>, > @attributes={"name"=>"Pete", "id"=>1}, @new_record=false> > > >> dl1.person.name > => "Pete" > > So, now Pete has a drivers license. > > Let''s try to give him another drivers license: > > >> dl2 = Driverslicense.new > => #<Driverslicense:0x233de2c @attributes={"person_id"=>nil}, > @new_record=true> > >> dl2.person_id = pete > => #<Person:0x2364d9c @errors=#<ActiveRecord::Errors:0x23511ac > @errors={}, @base=#<Person:0x2364d9c ...>>, > @attributes={"name"=>"Pete", "id"=>1}, @new_record=false> > >> > > >> dl2.person.name > => "Pete" > >> > > It appears that dmv has assigned 2 drivers licenses to Pete. > > Is it up to me to ''strengthen'' the has_one() method in AR? > > Here is info about my rails: > > $ script/about > About your application''s environment > Ruby version 1.8.4 (powerpc-darwin7.9.0) > RubyGems version 0.9.0 > Rails version 1.1.6 > Active Record version 1.14.4 > Action Pack version 1.12.5 > Action Web Service version 1.1.6 > Action Mailer version 1.2.5 > Active Support version 1.3.1 > > -Pete > http://GoodJobFastCar.com > goodjobfastcar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
In addition to validates_uniqueness_of your database probably has an option to enforce this kind of thing (eg add a unique index to the person_id column of driver_licenses Fred -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Peter Smith [gjfc] wrote:> > It appears that dmv has assigned 2 drivers licenses to Pete. > > Is it up to me to ''strengthen'' the has_one() method in AR? >Hi Pete The associations methods (has_one, belongs_to, etc) do not do any validation. They simply create meta-programmed accessor methods on your model classes that know how to query the DB for associated objects. Considering has_one vs. has_many, the name of the accessor is affected by the association method as well. In your case, Person.has_one :drivers_license will create an accessor "drivers_license" on your Person class (in memory). If you had used has_many, an accessor named "drivers_licenses" would have been created instead. Another difference is that, though the same finder SQL will be used regardless of whether you use has_one or has_many, the has_one finder will only return the first matching record, whereas the has_many will return all matching results. As for ensuring that a has_one association is enforced, a good practice is to define a unique index or key on your DB: If A has_one B, then a unique index should be defined on B''s foreign key into A (eg. B.A_id ). Hope this helps. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---