I''m trying to write an application that involves with three kinds of
inherited models:
The lowest is Person, a model merely used as records, and nothing else
of importance.
Officer inherits from Person, and unlike Person, stores a password for
verification and logging in.
Admin inherits from Officer, and is the same as Officers except there
must be at least one of them.
I want to make an internal method that allows me to turn a Person into
an Officer, an Officer to Admin, Admin to Person, etc. What''s a clean
method of upgrading/downgrading within this single-inheritance?
Here''s the source file, as well as a quick template for what I want to
see happen:
=======Person.rb=======class Person < ActiveRecord::Base
#first_name is required: must start with a capital
validates_presence_of :first_name
validates_format_of :first_name,
:with => /^[A-Z][a-zA-Z0-9, .]+$/
#last_name is required: must start with a capital
validates_presence_of :last_name
validates_format_of :last_name,
:with => /^[A-Z][a-zA-Z0-9, .]+$/
#rin is required: must be unique; also, must all be lowercases
#with 0 to 2 numbers following the letters.
validates_presence_of :rin
validates_format_of :rin,
:with => /^[a-z]+[0-9]{0,2}$/
validates_uniqueness_of :rin
#email must be unique, and it is required.
validates_presence_of :email
validates_format_of :email,
:with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/
validates_uniqueness_of :email
#year is required, and must be a 4 digit number greater than 2000
validates_presence_of :year
validates_numericality_of :year,
:only_integer => true
validates_length_of :year,
:is => 4
#turns a Person or Officer to Admin
def turn_to_admin
self[:type] = ''Admin''
#somehow update with Admin-based validations
self
end
#turns a Person or Admin to Officer
def turn_to_officer
self[:type] = ''Officer''
#somehow update with Officer-based validations
self
end
#technically, this does nothing
def turn_to_person
nil
end
protected
def validate
errors.add(:year, "should be between 2000 and 3000") if
( year.to_i < 2000 or year.to_i > 3000 )
end
#completely ignore the passwords
end
=======Officer.rb=======class Officer < Person
#take care of password thingy
validates_length_of :password, :minimum => 5
attr_accessor :password_confirmation
validates_confirmation_of :password
#some functions
def validate
errors.add_to_base("Missing password") if hashed_password.blank?
end
def self.authenticate(name, password)
person = self.find_by_rin(name)
if person
expected_password = encrypted_password(password, person.salt)
if person.hashed_password!=expected_password
person = nil
end
end
person
end
def password
@password
end
def password=(pwd)
@password = pwd
create_new_salt
self.hashed_password = Officer.encrypted_password(self.password,
self.salt)
end
#turn_to_admin is inherited from Person
#This does nothing
def turn_to_officer
nil
end
#turns an Officer or Admin
def turn_to_person
self[:type] = ''Person''
#somehow update with Officer-based validations
self
end
#careful of private statements
private
def self.encrypted_password(password, salt)
string_to_hash = password + "Japan is an island of interest" +
salt
Digest::SHA1.hexdigest(string_to_hash)
end
def create_new_salt
self.salt = (self.object_id * rand).to_s + rand.to_s
end
end
=======Admin.rb=======class Admin < Officer
#Make sure there''s at least one admin
def after_destroy
if Admin.count.zero?
raise "Can''t delete the last admin"
end
end
#turn_to_person is inherited by Officer
#Return nil, again
def turn_to_admin
nil
end
#turns an Admin to Officer
def turn_to_officer
self[:type] = ''Officer''
#somehow update with Officer-based validations
self
end
end
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---
Single table inheritance applies perfectly to this need, basically you have to add a type column, and build the people table with all the columns that any of the three classes will do, then both admin and officer have to inherit from person, (I never tested double inheritance) so some repetition at admin and officer model may happen, (you can use a mixin if you want to avoid that) On May 26, 4:05 pm, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I''m trying to write an application that involves with three kinds of > inherited models: > > The lowest is Person, a model merely used as records, and nothing else > of importance. > Officer inherits from Person, and unlike Person, stores a password for > verification and logging in. > Admin inherits from Officer, and is the same as Officers except there > must be at least one of them. > > I want to make an internal method that allows me to turn a Person into > an Officer, an Officer to Admin, Admin to Person, etc. What''s a clean > method of upgrading/downgrading within this single-inheritance? > > Here''s the source file, as well as a quick template for what I want to > see happen: > =======Person.rb=======> class Person < ActiveRecord::Base > #first_name is required: must start with a capital > validates_presence_of :first_name > validates_format_of :first_name, > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > #last_name is required: must start with a capital > validates_presence_of :last_name > validates_format_of :last_name, > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > #rin is required: must be unique; also, must all be lowercases > #with 0 to 2 numbers following the letters. > validates_presence_of :rin > validates_format_of :rin, > :with => /^[a-z]+[0-9]{0,2}$/ > validates_uniqueness_of :rin > > #email must be unique, and it is required. > validates_presence_of :email > validates_format_of :email, > :with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/ > validates_uniqueness_of :email > > #year is required, and must be a 4 digit number greater than 2000 > validates_presence_of :year > validates_numericality_of :year, > :only_integer => true > validates_length_of :year, > :is => 4 > > #turns a Person or Officer to Admin > def turn_to_admin > self[:type] = ''Admin'' > #somehow update with Admin-based validations > self > end > > #turns a Person or Admin to Officer > def turn_to_officer > self[:type] = ''Officer'' > #somehow update with Officer-based validations > self > end > > #technically, this does nothing > def turn_to_person > nil > end > > protected > > def validate > errors.add(:year, "should be between 2000 and 3000") if > ( year.to_i < 2000 or year.to_i > 3000 ) > end > > #completely ignore the passwords > end > =======Officer.rb=======> class Officer < Person > #take care of password thingy > validates_length_of :password, :minimum => 5 > > attr_accessor :password_confirmation > validates_confirmation_of :password > > #some functions > def validate > errors.add_to_base("Missing password") if hashed_password.blank? > end > > def self.authenticate(name, password) > person = self.find_by_rin(name) > if person > expected_password = encrypted_password(password, person.salt) > if person.hashed_password!=expected_password > person = nil > end > end > person > end > > def password > @password > end > > def password=(pwd) > @password = pwd > create_new_salt > self.hashed_password = Officer.encrypted_password(self.password, > self.salt) > end > > #turn_to_admin is inherited from Person > > #This does nothing > def turn_to_officer > nil > end > > #turns an Officer or Admin > def turn_to_person > self[:type] = ''Person'' > #somehow update with Officer-based validations > self > end > > #careful of private statements > private > > def self.encrypted_password(password, salt) > string_to_hash = password + "Japan is an island of interest" + > salt > Digest::SHA1.hexdigest(string_to_hash) > end > > def create_new_salt > self.salt = (self.object_id * rand).to_s + rand.to_s > end > end > =======Admin.rb=======> class Admin < Officer > > #Make sure there''s at least one admin > def after_destroy > if Admin.count.zero? > raise "Can''t delete the last admin" > end > end > > #turn_to_person is inherited by Officer > > #Return nil, again > def turn_to_admin > nil > end > > #turns an Admin to Officer > def turn_to_officer > self[:type] = ''Officer'' > #somehow update with Officer-based validations > self > end > end--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I think he''s got this already. What he''s trying to do is assign a person to be an Admin or an Officer. I think all you do is self.type = "Admin and then self.reload and it might work. On Tue, May 27, 2008 at 12:28 PM, Andres <paglayan-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Single table inheritance applies perfectly to this need, > basically you have to add a type column, > and build the people table with all the columns that any of the three > classes will do, > then both admin and officer have to inherit from person, > (I never tested double inheritance) > so some repetition at admin and officer model may happen, > (you can use a mixin if you want to avoid that) > > > On May 26, 4:05 pm, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > I''m trying to write an application that involves with three kinds of > > inherited models: > > > > The lowest is Person, a model merely used as records, and nothing else > > of importance. > > Officer inherits from Person, and unlike Person, stores a password for > > verification and logging in. > > Admin inherits from Officer, and is the same as Officers except there > > must be at least one of them. > > > > I want to make an internal method that allows me to turn a Person into > > an Officer, an Officer to Admin, Admin to Person, etc. What''s a clean > > method of upgrading/downgrading within this single-inheritance? > > > > Here''s the source file, as well as a quick template for what I want to > > see happen: > > =======Person.rb=======> > class Person < ActiveRecord::Base > > #first_name is required: must start with a capital > > validates_presence_of :first_name > > validates_format_of :first_name, > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > #last_name is required: must start with a capital > > validates_presence_of :last_name > > validates_format_of :last_name, > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > #rin is required: must be unique; also, must all be lowercases > > #with 0 to 2 numbers following the letters. > > validates_presence_of :rin > > validates_format_of :rin, > > :with => /^[a-z]+[0-9]{0,2}$/ > > validates_uniqueness_of :rin > > > > #email must be unique, and it is required. > > validates_presence_of :email > > validates_format_of :email, > > :with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/ > > validates_uniqueness_of :email > > > > #year is required, and must be a 4 digit number greater than 2000 > > validates_presence_of :year > > validates_numericality_of :year, > > :only_integer => true > > validates_length_of :year, > > :is => 4 > > > > #turns a Person or Officer to Admin > > def turn_to_admin > > self[:type] = ''Admin'' > > #somehow update with Admin-based validations > > self > > end > > > > #turns a Person or Admin to Officer > > def turn_to_officer > > self[:type] = ''Officer'' > > #somehow update with Officer-based validations > > self > > end > > > > #technically, this does nothing > > def turn_to_person > > nil > > end > > > > protected > > > > def validate > > errors.add(:year, "should be between 2000 and 3000") if > > ( year.to_i < 2000 or year.to_i > 3000 ) > > end > > > > #completely ignore the passwords > > end > > =======Officer.rb=======> > class Officer < Person > > #take care of password thingy > > validates_length_of :password, :minimum => 5 > > > > attr_accessor :password_confirmation > > validates_confirmation_of :password > > > > #some functions > > def validate > > errors.add_to_base("Missing password") if hashed_password.blank? > > end > > > > def self.authenticate(name, password) > > person = self.find_by_rin(name) > > if person > > expected_password = encrypted_password(password, person.salt) > > if person.hashed_password!=expected_password > > person = nil > > end > > end > > person > > end > > > > def password > > @password > > end > > > > def password=(pwd) > > @password = pwd > > create_new_salt > > self.hashed_password = Officer.encrypted_password(self.password, > > self.salt) > > end > > > > #turn_to_admin is inherited from Person > > > > #This does nothing > > def turn_to_officer > > nil > > end > > > > #turns an Officer or Admin > > def turn_to_person > > self[:type] = ''Person'' > > #somehow update with Officer-based validations > > self > > end > > > > #careful of private statements > > private > > > > def self.encrypted_password(password, salt) > > string_to_hash = password + "Japan is an island of interest" + > > salt > > Digest::SHA1.hexdigest(string_to_hash) > > end > > > > def create_new_salt > > self.salt = (self.object_id * rand).to_s + rand.to_s > > end > > end > > =======Admin.rb=======> > class Admin < Officer > > > > #Make sure there''s at least one admin > > def after_destroy > > if Admin.count.zero? > > raise "Can''t delete the last admin" > > end > > end > > > > #turn_to_person is inherited by Officer > > > > #Return nil, again > > def turn_to_admin > > nil > > end > > > > #turns an Admin to Officer > > def turn_to_officer > > self[:type] = ''Officer'' > > #somehow update with Officer-based validations > > self > > end > > end > > >-- Appreciated my help? Recommend me on Working With Rails http://workingwithrails.com/person/11030-ryan-bigg --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Yeah, I did already know. It''s is why I was asking something
else :-)!
Anyway, I tried the reload method:
-----
def test_changing_officer_to_member
officer = Officer.find(:first)
assert officer
assert officer.update_attributes(:type => ''Person'',
:password => ''Ha, ha, you cannot login!!!'',
:password_confirmation => ''Ha, ha, you cannot
login!!!'')
officer.reload
assert_equal officer.class.to_s, ''Person''
end
-----
It failed miserably:
-----
1) Failure:
test_changing_officer_to_member(OfficerTest)
[officer_test.rb:89:in `test_changing_officer_to_member''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
9 tests, 22 assertions, 1 failures, 0 errors
Process ruby exited with code 1
------
Any other solutions?
In addition, looking back at my test code, I noticed that:
------
def test_defective_new
officer = Officer.new( :first_name => ''John'',
:last_name => ''Doe'', :rin =>
''doej'',
:email => ''doej-IL7dBOYR4Vg@public.gmane.org'', :year
=> 2011,
:password => ''forka'')
assert officer.valid?
assert_equal officer.class.to_s, ''Officer''
end
-----
Passes. It shouldn''t. It should compare whether password and
confirmation password is the same thing, then give out an error. Why
by only giving a password, the model passes? After all, this test
passes correctly:
----
def test_unequal_password_confirmation
officer = Officer.new( :first_name => ''John'',
:last_name => ''Doe'', :rin =>
''doej'',
:email => ''doej-IL7dBOYR4Vg@public.gmane.org'', :year
=> 2011,
:password => ''jojoj'', :password_confirmation =>
''kkkkk'')
assert !officer.valid?
assert officer.errors.invalid?(:password)
end
----
Finally, random, but I''ll also like to test in "rake
script/console
testing". Unfortunately, the console doesn''t seem to realize
I''ve
downloaded the plugin "acts_as_list", nor does it seem to connect the
Database really well. What can I do to fix this? I''m using
InstantRails, by the way: does this have to do with anything?
On May 27, 12:26 am, "Ryan Bigg (Radar)"
<radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> I think he''s got this already.
>
> What he''s trying to do is assign a person to be an Admin or an
Officer. I
> think all you do is self.type = "Admin and then self.reload and it
might
> work.
>
>
>
> On Tue, May 27, 2008 at 12:28 PM, Andres
<pagla...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > Single table inheritance applies perfectly to this need,
> > basically you have to add a type column,
> > and build the people table with all the columns that any of the three
> > classes will do,
> > then both admin and officer have to inherit from person,
> > (I never tested double inheritance)
> > so some repetition at admin and officer model may happen,
> > (you can use a mixin if you want to avoid that)
>
> > On May 26, 4:05 pm, Taro
<japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > > I''m trying to write an application that involves with
three kinds of
> > > inherited models:
>
> > > The lowest is Person, a model merely used as records, and nothing
else
> > > of importance.
> > > Officer inherits from Person, and unlike Person, stores a
password for
> > > verification and logging in.
> > > Admin inherits from Officer, and is the same as Officers except
there
> > > must be at least one of them.
>
> > > I want to make an internal method that allows me to turn a Person
into
> > > an Officer, an Officer to Admin, Admin to Person, etc.
What''s a clean
> > > method of upgrading/downgrading within this single-inheritance?
>
> > > Here''s the source file, as well as a quick template for
what I want to
> > > see happen:
> > > =======Person.rb=======> > > class Person <
ActiveRecord::Base
> > > #first_name is required: must start with a capital
> > > validates_presence_of :first_name
> > > validates_format_of :first_name,
> > > :with => /^[A-Z][a-zA-Z0-9, .]+$/
>
> > > #last_name is required: must start with a capital
> > > validates_presence_of :last_name
> > > validates_format_of :last_name,
> > > :with => /^[A-Z][a-zA-Z0-9, .]+$/
>
> > > #rin is required: must be unique; also, must all be lowercases
> > > #with 0 to 2 numbers following the letters.
> > > validates_presence_of :rin
> > > validates_format_of :rin,
> > > :with => /^[a-z]+[0-9]{0,2}$/
> > > validates_uniqueness_of :rin
>
> > > #email must be unique, and it is required.
> > > validates_presence_of :email
> > > validates_format_of :email,
> > > :with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/
> > > validates_uniqueness_of :email
>
> > > #year is required, and must be a 4 digit number greater than
2000
> > > validates_presence_of :year
> > > validates_numericality_of :year,
> > > :only_integer => true
> > > validates_length_of :year,
> > > :is => 4
>
> > > #turns a Person or Officer to Admin
> > > def turn_to_admin
> > > self[:type] = ''Admin''
> > > #somehow update with Admin-based validations
> > > self
> > > end
>
> > > #turns a Person or Admin to Officer
> > > def turn_to_officer
> > > self[:type] = ''Officer''
> > > #somehow update with Officer-based validations
> > > self
> > > end
>
> > > #technically, this does nothing
> > > def turn_to_person
> > > nil
> > > end
>
> > > protected
>
> > > def validate
> > > errors.add(:year, "should be between 2000 and
3000") if
> > > ( year.to_i < 2000 or year.to_i > 3000 )
> > > end
>
> > > #completely ignore the passwords
> > > end
> > > =======Officer.rb=======> > > class Officer < Person
> > > #take care of password thingy
> > > validates_length_of :password, :minimum => 5
>
> > > attr_accessor :password_confirmation
> > > validates_confirmation_of :password
>
> > > #some functions
> > > def validate
> > > errors.add_to_base("Missing password") if
hashed_password.blank?
> > > end
>
> > > def self.authenticate(name, password)
> > > person = self.find_by_rin(name)
> > > if person
> > > expected_password = encrypted_password(password,
person.salt)
> > > if person.hashed_password!=expected_password
> > > person = nil
> > > end
> > > end
> > > person
> > > end
>
> > > def password
> > > @password
> > > end
>
> > > def password=(pwd)
> > > @password = pwd
> > > create_new_salt
> > > self.hashed_password =
Officer.encrypted_password(self.password,
> > > self.salt)
> > > end
>
> > > #turn_to_admin is inherited from Person
>
> > > #This does nothing
> > > def turn_to_officer
> > > nil
> > > end
>
> > > #turns an Officer or Admin
> > > def turn_to_person
> > > self[:type] = ''Person''
> > > #somehow update with Officer-based validations
> > > self
> > > end
>
> > > #careful of private statements
> > > private
>
> > > def self.encrypted_password(password, salt)
> > > string_to_hash = password + "Japan is an island of
interest" +
> > > salt
> > > Digest::SHA1.hexdigest(string_to_hash)
> > > end
>
> > > def create_new_salt
> > > self.salt = (self.object_id * rand).to_s + rand.to_s
> > > end
> > > end
> > > =======Admin.rb=======> > > class Admin < Officer
>
> > > #Make sure there''s at least one admin
> > > def after_destroy
> > > if Admin.count.zero?
> > > raise "Can''t delete the last admin"
> > > end
> > > end
>
> > > #turn_to_person is inherited by Officer
>
> > > #Return nil, again
> > > def turn_to_admin
> > > nil
> > > end
>
> > > #turns an Admin to Officer
> > > def turn_to_officer
> > > self[:type] = ''Officer''
> > > #somehow update with Officer-based validations
> > > self
> > > end
> > > end
>
> --
> Appreciated my help?
> Recommend me on Working With
Railshttp://workingwithrails.com/person/11030-ryan-bigg
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---
Reinitialize the variable seems to be the only option then, switch the type over to Officer and then do Officer.find(@person.id) and it may work that way. On Wed, May 28, 2008 at 9:47 AM, Taro <japtar10101-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Yeah, I did already know. It''s is why I was asking something > else :-)! > Anyway, I tried the reload method: > ----- > def test_changing_officer_to_member > officer = Officer.find(:first) > assert officer > assert officer.update_attributes(:type => ''Person'', > :password => ''Ha, ha, you cannot login!!!'', > :password_confirmation => ''Ha, ha, you cannot login!!!'') > officer.reload > assert_equal officer.class.to_s, ''Person'' > end > ----- > It failed miserably: > ----- > 1) Failure: > test_changing_officer_to_member(OfficerTest) > [officer_test.rb:89:in `test_changing_officer_to_member'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > 9 tests, 22 assertions, 1 failures, 0 errors > Process ruby exited with code 1 > ------ > Any other solutions? > > In addition, looking back at my test code, I noticed that: > ------ > def test_defective_new > officer = Officer.new( :first_name => ''John'', > :last_name => ''Doe'', :rin => ''doej'', > :email => ''doej-IL7dBOYR4Vg@public.gmane.org'', :year => 2011, > :password => ''forka'') > assert officer.valid? > assert_equal officer.class.to_s, ''Officer'' > end > ----- > Passes. It shouldn''t. It should compare whether password and > confirmation password is the same thing, then give out an error. Why > by only giving a password, the model passes? After all, this test > passes correctly: > ---- > def test_unequal_password_confirmation > officer = Officer.new( :first_name => ''John'', > :last_name => ''Doe'', :rin => ''doej'', > :email => ''doej-IL7dBOYR4Vg@public.gmane.org'', :year => 2011, > :password => ''jojoj'', :password_confirmation => ''kkkkk'') > assert !officer.valid? > assert officer.errors.invalid?(:password) > end > ---- > Finally, random, but I''ll also like to test in "rake script/console > testing". Unfortunately, the console doesn''t seem to realize I''ve > downloaded the plugin "acts_as_list", nor does it seem to connect the > Database really well. What can I do to fix this? I''m using > InstantRails, by the way: does this have to do with anything? > > On May 27, 12:26 am, "Ryan Bigg (Radar)" <radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > I think he''s got this already. > > > > What he''s trying to do is assign a person to be an Admin or an Officer. I > > think all you do is self.type = "Admin and then self.reload and it might > > work. > > > > > > > > On Tue, May 27, 2008 at 12:28 PM, Andres <pagla...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > Single table inheritance applies perfectly to this need, > > > basically you have to add a type column, > > > and build the people table with all the columns that any of the three > > > classes will do, > > > then both admin and officer have to inherit from person, > > > (I never tested double inheritance) > > > so some repetition at admin and officer model may happen, > > > (you can use a mixin if you want to avoid that) > > > > > On May 26, 4:05 pm, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > I''m trying to write an application that involves with three kinds of > > > > inherited models: > > > > > > The lowest is Person, a model merely used as records, and nothing > else > > > > of importance. > > > > Officer inherits from Person, and unlike Person, stores a password > for > > > > verification and logging in. > > > > Admin inherits from Officer, and is the same as Officers except there > > > > must be at least one of them. > > > > > > I want to make an internal method that allows me to turn a Person > into > > > > an Officer, an Officer to Admin, Admin to Person, etc. What''s a > clean > > > > method of upgrading/downgrading within this single-inheritance? > > > > > > Here''s the source file, as well as a quick template for what I want > to > > > > see happen: > > > > =======Person.rb=======> > > > class Person < ActiveRecord::Base > > > > #first_name is required: must start with a capital > > > > validates_presence_of :first_name > > > > validates_format_of :first_name, > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > > > #last_name is required: must start with a capital > > > > validates_presence_of :last_name > > > > validates_format_of :last_name, > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > > > #rin is required: must be unique; also, must all be lowercases > > > > #with 0 to 2 numbers following the letters. > > > > validates_presence_of :rin > > > > validates_format_of :rin, > > > > :with => /^[a-z]+[0-9]{0,2}$/ > > > > validates_uniqueness_of :rin > > > > > > #email must be unique, and it is required. > > > > validates_presence_of :email > > > > validates_format_of :email, > > > > :with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/ > > > > validates_uniqueness_of :email > > > > > > #year is required, and must be a 4 digit number greater than 2000 > > > > validates_presence_of :year > > > > validates_numericality_of :year, > > > > :only_integer => true > > > > validates_length_of :year, > > > > :is => 4 > > > > > > #turns a Person or Officer to Admin > > > > def turn_to_admin > > > > self[:type] = ''Admin'' > > > > #somehow update with Admin-based validations > > > > self > > > > end > > > > > > #turns a Person or Admin to Officer > > > > def turn_to_officer > > > > self[:type] = ''Officer'' > > > > #somehow update with Officer-based validations > > > > self > > > > end > > > > > > #technically, this does nothing > > > > def turn_to_person > > > > nil > > > > end > > > > > > protected > > > > > > def validate > > > > errors.add(:year, "should be between 2000 and 3000") if > > > > ( year.to_i < 2000 or year.to_i > 3000 ) > > > > end > > > > > > #completely ignore the passwords > > > > end > > > > =======Officer.rb=======> > > > class Officer < Person > > > > #take care of password thingy > > > > validates_length_of :password, :minimum => 5 > > > > > > attr_accessor :password_confirmation > > > > validates_confirmation_of :password > > > > > > #some functions > > > > def validate > > > > errors.add_to_base("Missing password") if hashed_password.blank? > > > > end > > > > > > def self.authenticate(name, password) > > > > person = self.find_by_rin(name) > > > > if person > > > > expected_password = encrypted_password(password, person.salt) > > > > if person.hashed_password!=expected_password > > > > person = nil > > > > end > > > > end > > > > person > > > > end > > > > > > def password > > > > @password > > > > end > > > > > > def password=(pwd) > > > > @password = pwd > > > > create_new_salt > > > > self.hashed_password = Officer.encrypted_password(self.password, > > > > self.salt) > > > > end > > > > > > #turn_to_admin is inherited from Person > > > > > > #This does nothing > > > > def turn_to_officer > > > > nil > > > > end > > > > > > #turns an Officer or Admin > > > > def turn_to_person > > > > self[:type] = ''Person'' > > > > #somehow update with Officer-based validations > > > > self > > > > end > > > > > > #careful of private statements > > > > private > > > > > > def self.encrypted_password(password, salt) > > > > string_to_hash = password + "Japan is an island of interest" + > > > > salt > > > > Digest::SHA1.hexdigest(string_to_hash) > > > > end > > > > > > def create_new_salt > > > > self.salt = (self.object_id * rand).to_s + rand.to_s > > > > end > > > > end > > > > =======Admin.rb=======> > > > class Admin < Officer > > > > > > #Make sure there''s at least one admin > > > > def after_destroy > > > > if Admin.count.zero? > > > > raise "Can''t delete the last admin" > > > > end > > > > end > > > > > > #turn_to_person is inherited by Officer > > > > > > #Return nil, again > > > > def turn_to_admin > > > > nil > > > > end > > > > > > #turns an Admin to Officer > > > > def turn_to_officer > > > > self[:type] = ''Officer'' > > > > #somehow update with Officer-based validations > > > > self > > > > end > > > > end > > > > -- > > Appreciated my help? > > Recommend me on Working With Railshttp:// > workingwithrails.com/person/11030-ryan-bigg > > >-- Appreciated my help? Recommend me on Working With Rails http://workingwithrails.com/person/11030-ryan-bigg --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Behold!!!
-----
def test_changing_officer_to_member
officer = Officer.find(:first)
assert officer
assert officer.update_attributes(:type => ''Person'',
:password => ''Ha, ha, you cannot login!!!'',
:password_confirmation => ''Ha, ha, you cannot
login!!!'')
officer.reload
assert_equal officer.class.to_s, ''Person''
end
def test_changing_officer_to_member2
officer = Officer.find(:first)
assert officer
officer.type = ''Person''
officer.reload
assert_equal officer.class.to_s, ''Person''
end
def test_changing_officer_to_member3
officer = Officer.find(:first)
assert officer
officer[:type] = ''Person''
officer.reload
assert_equal officer.class.to_s, ''Person''
end
def test_changing_officer_to_member4
officer = Officer.find(:first)
assert officer
officer[:type] = ''Person''
officer = Officer.find(officer.id)
assert_equal officer.class.to_s, ''Person''
end
def test_changing_officer_to_member5
officer = Officer.find(:first)
assert officer
officer[:type] = ''Person''
officer = Person.find(officer.id)
assert_equal officer.class.to_s, ''Person''
end
def test_changing_officer_to_member6
officer = Officer.find(:first)
assert officer
officer.type = ''Person''
officer = Person.find(officer.id)
assert_equal officer.class.to_s, ''Person''
end
-----
1) Failure:
test_changing_officer_to_member(OfficerTest)
[officer_test.rb:90:in `test_changing_officer_to_member''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
2) Failure:
test_changing_officer_to_member2(OfficerTest)
[officer_test.rb:98:in `test_changing_officer_to_member2''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
3) Failure:
test_changing_officer_to_member3(OfficerTest)
[officer_test.rb:106:in `test_changing_officer_to_member3''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
4) Failure:
test_changing_officer_to_member4(OfficerTest)
[officer_test.rb:114:in `test_changing_officer_to_member4''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
5) Failure:
test_changing_officer_to_member5(OfficerTest)
[officer_test.rb:122:in `test_changing_officer_to_member5''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
6) Failure:
test_changing_officer_to_member6(OfficerTest)
[officer_test.rb:130:in `test_changing_officer_to_member6''
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
active_support/testing/default.rb:7:in `run'']:
<"Officer"> expected but was
<"Person">.
On May 27, 8:19 pm, "Ryan Bigg (Radar)"
<radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> Reinitialize the variable seems to be the only option then, switch the type
> over to Officer and then do Officer.find(@person.id) and it may work that
> way.
>
>
>
> On Wed, May 28, 2008 at 9:47 AM, Taro
<japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > Yeah, I did already know. It''s is why I was asking something
> > else :-)!
> > Anyway, I tried the reload method:
> > -----
> > def test_changing_officer_to_member
> > officer = Officer.find(:first)
> > assert officer
> > assert officer.update_attributes(:type =>
''Person'',
> > :password => ''Ha, ha, you cannot login!!!'',
> > :password_confirmation => ''Ha, ha, you cannot
login!!!'')
> > officer.reload
> > assert_equal officer.class.to_s, ''Person''
> > end
> > -----
> > It failed miserably:
> > -----
> > 1) Failure:
> > test_changing_officer_to_member(OfficerTest)
> > [officer_test.rb:89:in `test_changing_officer_to_member''
> > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/
> > active_support/testing/default.rb:7:in `run'']:
> > <"Officer"> expected but was
> > <"Person">.
>
> > 9 tests, 22 assertions, 1 failures, 0 errors
> > Process ruby exited with code 1
> > ------
> > Any other solutions?
>
> > In addition, looking back at my test code, I noticed that:
> > ------
> > def test_defective_new
> > officer = Officer.new( :first_name => ''John'',
> > :last_name => ''Doe'', :rin =>
''doej'',
> > :email =>
''d...-IL7dBOYR4Vg@public.gmane.org'', :year => 2011,
> > :password => ''forka'')
> > assert officer.valid?
> > assert_equal officer.class.to_s, ''Officer''
> > end
> > -----
> > Passes. It shouldn''t. It should compare whether password
and
> > confirmation password is the same thing, then give out an error. Why
> > by only giving a password, the model passes? After all, this test
> > passes correctly:
> > ----
> > def test_unequal_password_confirmation
> > officer = Officer.new( :first_name => ''John'',
> > :last_name => ''Doe'', :rin =>
''doej'',
> > :email =>
''d...-IL7dBOYR4Vg@public.gmane.org'', :year => 2011,
> > :password => ''jojoj'', :password_confirmation
=> ''kkkkk'')
> > assert !officer.valid?
> > assert officer.errors.invalid?(:password)
> > end
> > ----
> > Finally, random, but I''ll also like to test in "rake
script/console
> > testing". Unfortunately, the console doesn''t seem to
realize I''ve
> > downloaded the plugin "acts_as_list", nor does it seem to
connect the
> > Database really well. What can I do to fix this? I''m using
> > InstantRails, by the way: does this have to do with anything?
>
> > On May 27, 12:26 am, "Ryan Bigg (Radar)"
<radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > wrote:
> > > I think he''s got this already.
>
> > > What he''s trying to do is assign a person to be an Admin
or an Officer. I
> > > think all you do is self.type = "Admin and then self.reload
and it might
> > > work.
>
> > > On Tue, May 27, 2008 at 12:28 PM, Andres
<pagla...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > > > Single table inheritance applies perfectly to this need,
> > > > basically you have to add a type column,
> > > > and build the people table with all the columns that any of
the three
> > > > classes will do,
> > > > then both admin and officer have to inherit from person,
> > > > (I never tested double inheritance)
> > > > so some repetition at admin and officer model may happen,
> > > > (you can use a mixin if you want to avoid that)
>
> > > > On May 26, 4:05 pm, Taro
<japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > > > > I''m trying to write an application that
involves with three kinds of
> > > > > inherited models:
>
> > > > > The lowest is Person, a model merely used as records,
and nothing
> > else
> > > > > of importance.
> > > > > Officer inherits from Person, and unlike Person, stores
a password
> > for
> > > > > verification and logging in.
> > > > > Admin inherits from Officer, and is the same as
Officers except there
> > > > > must be at least one of them.
>
> > > > > I want to make an internal method that allows me to
turn a Person
> > into
> > > > > an Officer, an Officer to Admin, Admin to Person, etc.
What''s a
> > clean
> > > > > method of upgrading/downgrading within this
single-inheritance?
>
> > > > > Here''s the source file, as well as a quick
template for what I want
> > to
> > > > > see happen:
> > > > > =======Person.rb=======> > > > > class
Person < ActiveRecord::Base
> > > > > #first_name is required: must start with a capital
> > > > > validates_presence_of :first_name
> > > > > validates_format_of :first_name,
> > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/
>
> > > > > #last_name is required: must start with a capital
> > > > > validates_presence_of :last_name
> > > > > validates_format_of :last_name,
> > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/
>
> > > > > #rin is required: must be unique; also, must all be
lowercases
> > > > > #with 0 to 2 numbers following the letters.
> > > > > validates_presence_of :rin
> > > > > validates_format_of :rin,
> > > > > :with => /^[a-z]+[0-9]{0,2}$/
> > > > > validates_uniqueness_of :rin
>
> > > > > #email must be unique, and it is required.
> > > > > validates_presence_of :email
> > > > > validates_format_of :email,
> > > > > :with =>
/^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/
> > > > > validates_uniqueness_of :email
>
> > > > > #year is required, and must be a 4 digit number
greater than 2000
> > > > > validates_presence_of :year
> > > > > validates_numericality_of :year,
> > > > > :only_integer => true
> > > > > validates_length_of :year,
> > > > > :is => 4
>
> > > > > #turns a Person or Officer to Admin
> > > > > def turn_to_admin
> > > > > self[:type] = ''Admin''
> > > > > #somehow update with Admin-based validations
> > > > > self
> > > > > end
>
> > > > > #turns a Person or Admin to Officer
> > > > > def turn_to_officer
> > > > > self[:type] = ''Officer''
> > > > > #somehow update with Officer-based validations
> > > > > self
> > > > > end
>
> > > > > #technically, this does nothing
> > > > > def turn_to_person
> > > > > nil
> > > > > end
>
> > > > > protected
>
> > > > > def validate
> > > > > errors.add(:year, "should be between 2000 and
3000") if
> > > > > ( year.to_i < 2000 or year.to_i > 3000 )
> > > > > end
>
> > > > > #completely ignore the passwords
> > > > > end
> > > > > =======Officer.rb=======> > > > > class
Officer < Person
> > > > > #take care of password thingy
> > > > > validates_length_of :password, :minimum => 5
>
> > > > > attr_accessor :password_confirmation
> > > > > validates_confirmation_of :password
>
> > > > > #some functions
> > > > > def validate
> > > > > errors.add_to_base("Missing password") if
hashed_password.blank?
> > > > > end
>
> > > > > def self.authenticate(name, password)
> > > > > person = self.find_by_rin(name)
> > > > > if person
> > > > > expected_password = encrypted_password(password,
person.salt)
> > > > > if person.hashed_password!=expected_password
> > > > > person = nil
> > > > > end
> > > > > end
> > > > > person
> > > > > end
>
> > > > > def password
> > > > > @password
> > > > > end
>
> > > > > def password=(pwd)
> > > > > @password = pwd
> > > > > create_new_salt
> > > > > self.hashed_password =
Officer.encrypted_password(self.password,
> > > > > self.salt)
> > > > > end
>
> > > > > #turn_to_admin is inherited from Person
>
> > > > > #This does nothing
> > > > > def turn_to_officer
> > > > > nil
> > > > > end
>
> > > > > #turns an Officer or Admin
> > > > > def turn_to_person
> > > > > self[:type] = ''Person''
> > > > > #somehow update with Officer-based validations
> > > > > self
> > > > > end
>
> > > > > #careful of private statements
> > > > > private
>
> > > > > def self.encrypted_password(password, salt)
> > > > > string_to_hash = password + "Japan is an
island of interest" +
> > > > > salt
> > > > > Digest::SHA1.hexdigest(string_to_hash)
> > > > > end
>
> > > > > def create_new_salt
> > > > > self.salt = (self.object_id * rand).to_s +
rand.to_s
> > > > > end
> > > > > end
> > > > > =======Admin.rb=======> > > > > class
Admin < Officer
>
> > > > > #Make sure there''s at least one admin
> > > > > def after_destroy
> > > > > if Admin.count.zero?
> > > > > raise "Can''t delete the last
admin"
> > > > > end
> > > > > end
>
> > > > > #turn_to_person is inherited by Officer
>
> > > > > #Return nil, again
> > > > > def turn_to_admin
> > > > > nil
> > > > > end
>
> > > > > #turns an Admin to Officer
> > > > > def turn_to_officer
> > > > > self[:type] = ''Officer''
> > > > > #somehow update with Officer-based validations
> > > > > self
> > > > > end
> > > > > end
>
> > > --
> > > Appreciated my help?
> > > Recommend me on Working With Railshttp://
> > workingwithrails.com/person/11030-ryan-bigg
>
> --
> Appreciated my help?
> Recommend me on Working With
Railshttp://workingwithrails.com/person/11030-ryan-bigg
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---
Your test is wrong. You should be doing: person = Person.find(id) person.type = "Officer" person.save officer = Officer.find(id) officer.class == Officer And that will return true. On Wed, May 28, 2008 at 9:55 AM, Taro <japtar10101-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Behold!!! > > ----- > def test_changing_officer_to_member > officer = Officer.find(:first) > assert officer > assert officer.update_attributes(:type => ''Person'', > :password => ''Ha, ha, you cannot login!!!'', > :password_confirmation => ''Ha, ha, you cannot login!!!'') > officer.reload > assert_equal officer.class.to_s, ''Person'' > end > > def test_changing_officer_to_member2 > officer = Officer.find(:first) > assert officer > officer.type = ''Person'' > officer.reload > assert_equal officer.class.to_s, ''Person'' > end > > def test_changing_officer_to_member3 > officer = Officer.find(:first) > assert officer > officer[:type] = ''Person'' > officer.reload > assert_equal officer.class.to_s, ''Person'' > end > > def test_changing_officer_to_member4 > officer = Officer.find(:first) > assert officer > officer[:type] = ''Person'' > officer = Officer.find(officer.id) > assert_equal officer.class.to_s, ''Person'' > end > > def test_changing_officer_to_member5 > officer = Officer.find(:first) > assert officer > officer[:type] = ''Person'' > officer = Person.find(officer.id) > assert_equal officer.class.to_s, ''Person'' > end > > def test_changing_officer_to_member6 > officer = Officer.find(:first) > assert officer > officer.type = ''Person'' > officer = Person.find(officer.id) > assert_equal officer.class.to_s, ''Person'' > end > ----- > > > 1) Failure: > test_changing_officer_to_member(OfficerTest) > [officer_test.rb:90:in `test_changing_officer_to_member'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > 2) Failure: > test_changing_officer_to_member2(OfficerTest) > [officer_test.rb:98:in `test_changing_officer_to_member2'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > 3) Failure: > test_changing_officer_to_member3(OfficerTest) > [officer_test.rb:106:in `test_changing_officer_to_member3'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > 4) Failure: > test_changing_officer_to_member4(OfficerTest) > [officer_test.rb:114:in `test_changing_officer_to_member4'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > 5) Failure: > test_changing_officer_to_member5(OfficerTest) > [officer_test.rb:122:in `test_changing_officer_to_member5'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > 6) Failure: > test_changing_officer_to_member6(OfficerTest) > [officer_test.rb:130:in `test_changing_officer_to_member6'' > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > active_support/testing/default.rb:7:in `run'']: > <"Officer"> expected but was > <"Person">. > > On May 27, 8:19 pm, "Ryan Bigg (Radar)" <radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > Reinitialize the variable seems to be the only option then, switch the > type > > over to Officer and then do Officer.find(@person.id) and it may work > that > > way. > > > > > > > > On Wed, May 28, 2008 at 9:47 AM, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > Yeah, I did already know. It''s is why I was asking something > > > else :-)! > > > Anyway, I tried the reload method: > > > ----- > > > def test_changing_officer_to_member > > > officer = Officer.find(:first) > > > assert officer > > > assert officer.update_attributes(:type => ''Person'', > > > :password => ''Ha, ha, you cannot login!!!'', > > > :password_confirmation => ''Ha, ha, you cannot login!!!'') > > > officer.reload > > > assert_equal officer.class.to_s, ''Person'' > > > end > > > ----- > > > It failed miserably: > > > ----- > > > 1) Failure: > > > test_changing_officer_to_member(OfficerTest) > > > [officer_test.rb:89:in `test_changing_officer_to_member'' > > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > > active_support/testing/default.rb:7:in `run'']: > > > <"Officer"> expected but was > > > <"Person">. > > > > > 9 tests, 22 assertions, 1 failures, 0 errors > > > Process ruby exited with code 1 > > > ------ > > > Any other solutions? > > > > > In addition, looking back at my test code, I noticed that: > > > ------ > > > def test_defective_new > > > officer = Officer.new( :first_name => ''John'', > > > :last_name => ''Doe'', :rin => ''doej'', > > > :email => ''d...-IL7dBOYR4Vg@public.gmane.org'', :year => 2011, > > > :password => ''forka'') > > > assert officer.valid? > > > assert_equal officer.class.to_s, ''Officer'' > > > end > > > ----- > > > Passes. It shouldn''t. It should compare whether password and > > > confirmation password is the same thing, then give out an error. Why > > > by only giving a password, the model passes? After all, this test > > > passes correctly: > > > ---- > > > def test_unequal_password_confirmation > > > officer = Officer.new( :first_name => ''John'', > > > :last_name => ''Doe'', :rin => ''doej'', > > > :email => ''d...-IL7dBOYR4Vg@public.gmane.org'', :year => 2011, > > > :password => ''jojoj'', :password_confirmation => ''kkkkk'') > > > assert !officer.valid? > > > assert officer.errors.invalid?(:password) > > > end > > > ---- > > > Finally, random, but I''ll also like to test in "rake script/console > > > testing". Unfortunately, the console doesn''t seem to realize I''ve > > > downloaded the plugin "acts_as_list", nor does it seem to connect the > > > Database really well. What can I do to fix this? I''m using > > > InstantRails, by the way: does this have to do with anything? > > > > > On May 27, 12:26 am, "Ryan Bigg (Radar)" <radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > > > wrote: > > > > I think he''s got this already. > > > > > > What he''s trying to do is assign a person to be an Admin or an > Officer. I > > > > think all you do is self.type = "Admin and then self.reload and it > might > > > > work. > > > > > > On Tue, May 27, 2008 at 12:28 PM, Andres <pagla...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > Single table inheritance applies perfectly to this need, > > > > > basically you have to add a type column, > > > > > and build the people table with all the columns that any of the > three > > > > > classes will do, > > > > > then both admin and officer have to inherit from person, > > > > > (I never tested double inheritance) > > > > > so some repetition at admin and officer model may happen, > > > > > (you can use a mixin if you want to avoid that) > > > > > > > On May 26, 4:05 pm, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > I''m trying to write an application that involves with three kinds > of > > > > > > inherited models: > > > > > > > > The lowest is Person, a model merely used as records, and nothing > > > else > > > > > > of importance. > > > > > > Officer inherits from Person, and unlike Person, stores a > password > > > for > > > > > > verification and logging in. > > > > > > Admin inherits from Officer, and is the same as Officers except > there > > > > > > must be at least one of them. > > > > > > > > I want to make an internal method that allows me to turn a Person > > > into > > > > > > an Officer, an Officer to Admin, Admin to Person, etc. What''s a > > > clean > > > > > > method of upgrading/downgrading within this single-inheritance? > > > > > > > > Here''s the source file, as well as a quick template for what I > want > > > to > > > > > > see happen: > > > > > > =======Person.rb=======> > > > > > class Person < ActiveRecord::Base > > > > > > #first_name is required: must start with a capital > > > > > > validates_presence_of :first_name > > > > > > validates_format_of :first_name, > > > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > > > > > #last_name is required: must start with a capital > > > > > > validates_presence_of :last_name > > > > > > validates_format_of :last_name, > > > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > > > > > #rin is required: must be unique; also, must all be lowercases > > > > > > #with 0 to 2 numbers following the letters. > > > > > > validates_presence_of :rin > > > > > > validates_format_of :rin, > > > > > > :with => /^[a-z]+[0-9]{0,2}$/ > > > > > > validates_uniqueness_of :rin > > > > > > > > #email must be unique, and it is required. > > > > > > validates_presence_of :email > > > > > > validates_format_of :email, > > > > > > :with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/ > > > > > > validates_uniqueness_of :email > > > > > > > > #year is required, and must be a 4 digit number greater than > 2000 > > > > > > validates_presence_of :year > > > > > > validates_numericality_of :year, > > > > > > :only_integer => true > > > > > > validates_length_of :year, > > > > > > :is => 4 > > > > > > > > #turns a Person or Officer to Admin > > > > > > def turn_to_admin > > > > > > self[:type] = ''Admin'' > > > > > > #somehow update with Admin-based validations > > > > > > self > > > > > > end > > > > > > > > #turns a Person or Admin to Officer > > > > > > def turn_to_officer > > > > > > self[:type] = ''Officer'' > > > > > > #somehow update with Officer-based validations > > > > > > self > > > > > > end > > > > > > > > #technically, this does nothing > > > > > > def turn_to_person > > > > > > nil > > > > > > end > > > > > > > > protected > > > > > > > > def validate > > > > > > errors.add(:year, "should be between 2000 and 3000") if > > > > > > ( year.to_i < 2000 or year.to_i > 3000 ) > > > > > > end > > > > > > > > #completely ignore the passwords > > > > > > end > > > > > > =======Officer.rb=======> > > > > > class Officer < Person > > > > > > #take care of password thingy > > > > > > validates_length_of :password, :minimum => 5 > > > > > > > > attr_accessor :password_confirmation > > > > > > validates_confirmation_of :password > > > > > > > > #some functions > > > > > > def validate > > > > > > errors.add_to_base("Missing password") if > hashed_password.blank? > > > > > > end > > > > > > > > def self.authenticate(name, password) > > > > > > person = self.find_by_rin(name) > > > > > > if person > > > > > > expected_password = encrypted_password(password, > person.salt) > > > > > > if person.hashed_password!=expected_password > > > > > > person = nil > > > > > > end > > > > > > end > > > > > > person > > > > > > end > > > > > > > > def password > > > > > > @password > > > > > > end > > > > > > > > def password=(pwd) > > > > > > @password = pwd > > > > > > create_new_salt > > > > > > self.hashed_password > Officer.encrypted_password(self.password, > > > > > > self.salt) > > > > > > end > > > > > > > > #turn_to_admin is inherited from Person > > > > > > > > #This does nothing > > > > > > def turn_to_officer > > > > > > nil > > > > > > end > > > > > > > > #turns an Officer or Admin > > > > > > def turn_to_person > > > > > > self[:type] = ''Person'' > > > > > > #somehow update with Officer-based validations > > > > > > self > > > > > > end > > > > > > > > #careful of private statements > > > > > > private > > > > > > > > def self.encrypted_password(password, salt) > > > > > > string_to_hash = password + "Japan is an island of interest" > + > > > > > > salt > > > > > > Digest::SHA1.hexdigest(string_to_hash) > > > > > > end > > > > > > > > def create_new_salt > > > > > > self.salt = (self.object_id * rand).to_s + rand.to_s > > > > > > end > > > > > > end > > > > > > =======Admin.rb=======> > > > > > class Admin < Officer > > > > > > > > #Make sure there''s at least one admin > > > > > > def after_destroy > > > > > > if Admin.count.zero? > > > > > > raise "Can''t delete the last admin" > > > > > > end > > > > > > end > > > > > > > > #turn_to_person is inherited by Officer > > > > > > > > #Return nil, again > > > > > > def turn_to_admin > > > > > > nil > > > > > > end > > > > > > > > #turns an Admin to Officer > > > > > > def turn_to_officer > > > > > > self[:type] = ''Officer'' > > > > > > #somehow update with Officer-based validations > > > > > > self > > > > > > end > > > > > > end > > > > > > -- > > > > Appreciated my help? > > > > Recommend me on Working With Railshttp:// > > > workingwithrails.com/person/11030-ryan-bigg > > > > -- > > Appreciated my help? > > Recommend me on Working With Railshttp:// > workingwithrails.com/person/11030-ryan-bigg > > >-- Appreciated my help? Recommend me on Working With Rails http://workingwithrails.com/person/11030-ryan-bigg --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Oh, whoops. Anyway, it did work. I''m curious about why "person.type = " works. I read somewhere that the correct syntax should be "person[:type] = ", due to the fact that ".type" is a (deprecated) class method. On May 27, 9:33 pm, "Ryan Bigg (Radar)" <radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Your test is wrong. You should be doing: > > person = Person.find(id) > person.type = "Officer" > person.save > officer = Officer.find(id) > officer.class == Officer > > And that will return true. > > On Wed, May 28, 2008 at 9:55 AM, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Behold!!! > > > ----- > > def test_changing_officer_to_member > > officer = Officer.find(:first) > > assert officer > > assert officer.update_attributes(:type => ''Person'', > > :password => ''Ha, ha, you cannot login!!!'', > > :password_confirmation => ''Ha, ha, you cannot login!!!'') > > officer.reload > > assert_equal officer.class.to_s, ''Person'' > > end > > > def test_changing_officer_to_member2 > > officer = Officer.find(:first) > > assert officer > > officer.type = ''Person'' > > officer.reload > > assert_equal officer.class.to_s, ''Person'' > > end > > > def test_changing_officer_to_member3 > > officer = Officer.find(:first) > > assert officer > > officer[:type] = ''Person'' > > officer.reload > > assert_equal officer.class.to_s, ''Person'' > > end > > > def test_changing_officer_to_member4 > > officer = Officer.find(:first) > > assert officer > > officer[:type] = ''Person'' > > officer = Officer.find(officer.id) > > assert_equal officer.class.to_s, ''Person'' > > end > > > def test_changing_officer_to_member5 > > officer = Officer.find(:first) > > assert officer > > officer[:type] = ''Person'' > > officer = Person.find(officer.id) > > assert_equal officer.class.to_s, ''Person'' > > end > > > def test_changing_officer_to_member6 > > officer = Officer.find(:first) > > assert officer > > officer.type = ''Person'' > > officer = Person.find(officer.id) > > assert_equal officer.class.to_s, ''Person'' > > end > > ----- > > > 1) Failure: > > test_changing_officer_to_member(OfficerTest) > > [officer_test.rb:90:in `test_changing_officer_to_member'' > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > active_support/testing/default.rb:7:in `run'']: > > <"Officer"> expected but was > > <"Person">. > > > 2) Failure: > > test_changing_officer_to_member2(OfficerTest) > > [officer_test.rb:98:in `test_changing_officer_to_member2'' > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > active_support/testing/default.rb:7:in `run'']: > > <"Officer"> expected but was > > <"Person">. > > > 3) Failure: > > test_changing_officer_to_member3(OfficerTest) > > [officer_test.rb:106:in `test_changing_officer_to_member3'' > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > active_support/testing/default.rb:7:in `run'']: > > <"Officer"> expected but was > > <"Person">. > > > 4) Failure: > > test_changing_officer_to_member4(OfficerTest) > > [officer_test.rb:114:in `test_changing_officer_to_member4'' > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > active_support/testing/default.rb:7:in `run'']: > > <"Officer"> expected but was > > <"Person">. > > > 5) Failure: > > test_changing_officer_to_member5(OfficerTest) > > [officer_test.rb:122:in `test_changing_officer_to_member5'' > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > active_support/testing/default.rb:7:in `run'']: > > <"Officer"> expected but was > > <"Person">. > > > 6) Failure: > > test_changing_officer_to_member6(OfficerTest) > > [officer_test.rb:130:in `test_changing_officer_to_member6'' > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > active_support/testing/default.rb:7:in `run'']: > > <"Officer"> expected but was > > <"Person">. > > > On May 27, 8:19 pm, "Ryan Bigg (Radar)" <radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > > wrote: > > > Reinitialize the variable seems to be the only option then, switch the > > type > > > over to Officer and then do Officer.find(@person.id) and it may work > > that > > > way. > > > > On Wed, May 28, 2008 at 9:47 AM, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > Yeah, I did already know. It''s is why I was asking something > > > > else :-)! > > > > Anyway, I tried the reload method: > > > > ----- > > > > def test_changing_officer_to_member > > > > officer = Officer.find(:first) > > > > assert officer > > > > assert officer.update_attributes(:type => ''Person'', > > > > :password => ''Ha, ha, you cannot login!!!'', > > > > :password_confirmation => ''Ha, ha, you cannot login!!!'') > > > > officer.reload > > > > assert_equal officer.class.to_s, ''Person'' > > > > end > > > > ----- > > > > It failed miserably: > > > > ----- > > > > 1) Failure: > > > > test_changing_officer_to_member(OfficerTest) > > > > [officer_test.rb:89:in `test_changing_officer_to_member'' > > > > c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2-/lib/ > > > > active_support/testing/default.rb:7:in `run'']: > > > > <"Officer"> expected but was > > > > <"Person">. > > > > > 9 tests, 22 assertions, 1 failures, 0 errors > > > > Process ruby exited with code 1 > > > > ------ > > > > Any other solutions? > > > > > In addition, looking back at my test code, I noticed that: > > > > ------ > > > > def test_defective_new > > > > officer = Officer.new( :first_name => ''John'', > > > > :last_name => ''Doe'', :rin => ''doej'', > > > > :email => ''d...-IL7dBOYR4Vg@public.gmane.org'', :year => 2011, > > > > :password => ''forka'') > > > > assert officer.valid? > > > > assert_equal officer.class.to_s, ''Officer'' > > > > end > > > > ----- > > > > Passes. It shouldn''t. It should compare whether password and > > > > confirmation password is the same thing, then give out an error. Why > > > > by only giving a password, the model passes? After all, this test > > > > passes correctly: > > > > ---- > > > > def test_unequal_password_confirmation > > > > officer = Officer.new( :first_name => ''John'', > > > > :last_name => ''Doe'', :rin => ''doej'', > > > > :email => ''d...-IL7dBOYR4Vg@public.gmane.org'', :year => 2011, > > > > :password => ''jojoj'', :password_confirmation => ''kkkkk'') > > > > assert !officer.valid? > > > > assert officer.errors.invalid?(:password) > > > > end > > > > ---- > > > > Finally, random, but I''ll also like to test in "rake script/console > > > > testing". Unfortunately, the console doesn''t seem to realize I''ve > > > > downloaded the plugin "acts_as_list", nor does it seem to connect the > > > > Database really well. What can I do to fix this? I''m using > > > > InstantRails, by the way: does this have to do with anything? > > > > > On May 27, 12:26 am, "Ryan Bigg (Radar)" <radarliste...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > > > > wrote: > > > > > I think he''s got this already. > > > > > > What he''s trying to do is assign a person to be an Admin or an > > Officer. I > > > > > think all you do is self.type = "Admin and then self.reload and it > > might > > > > > work. > > > > > > On Tue, May 27, 2008 at 12:28 PM, Andres <pagla...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > Single table inheritance applies perfectly to this need, > > > > > > basically you have to add a type column, > > > > > > and build the people table with all the columns that any of the > > three > > > > > > classes will do, > > > > > > then both admin and officer have to inherit from person, > > > > > > (I never tested double inheritance) > > > > > > so some repetition at admin and officer model may happen, > > > > > > (you can use a mixin if you want to avoid that) > > > > > > > On May 26, 4:05 pm, Taro <japtar10...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > > I''m trying to write an application that involves with three kinds > > of > > > > > > > inherited models: > > > > > > > > The lowest is Person, a model merely used as records, and nothing > > > > else > > > > > > > of importance. > > > > > > > Officer inherits from Person, and unlike Person, stores a > > password > > > > for > > > > > > > verification and logging in. > > > > > > > Admin inherits from Officer, and is the same as Officers except > > there > > > > > > > must be at least one of them. > > > > > > > > I want to make an internal method that allows me to turn a Person > > > > into > > > > > > > an Officer, an Officer to Admin, Admin to Person, etc. What''s a > > > > clean > > > > > > > method of upgrading/downgrading within this single-inheritance? > > > > > > > > Here''s the source file, as well as a quick template for what I > > want > > > > to > > > > > > > see happen: > > > > > > > =======Person.rb=======> > > > > > > class Person < ActiveRecord::Base > > > > > > > #first_name is required: must start with a capital > > > > > > > validates_presence_of :first_name > > > > > > > validates_format_of :first_name, > > > > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > > > > > #last_name is required: must start with a capital > > > > > > > validates_presence_of :last_name > > > > > > > validates_format_of :last_name, > > > > > > > :with => /^[A-Z][a-zA-Z0-9, .]+$/ > > > > > > > > #rin is required: must be unique; also, must all be lowercases > > > > > > > #with 0 to 2 numbers following the letters. > > > > > > > validates_presence_of :rin > > > > > > > validates_format_of :rin, > > > > > > > :with => /^[a-z]+[0-9]{0,2}$/ > > > > > > > validates_uniqueness_of :rin > > > > > > > > #email must be unique, and it is required. > > > > > > > validates_presence_of :email > > > > > > > validates_format_of :email, > > > > > > > :with => /^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-z]{2,3}){1,2}$/ > > > > > > > validates_uniqueness_of :email > > > > > > > > #year is required, and must be a 4 digit number greater than > > 2000 > > > > > > > validates_presence_of :year > > > > > > > validates_numericality_of :year, > > > > > > > :only_integer => true > > > > > > > validates_length_of :year, > > > > > > > :is => 4 > > > > > > > > #turns a Person or Officer to Admin > > > > > > > def turn_to_admin > > > > > > > self[:type] = ''Admin'' > > > > > > > #somehow update with Admin-based validations > > > > > > > self > > > > > > > end > > > > > > > > #turns a Person or Admin to Officer > > > > > > > def turn_to_officer > > > > > > > self[:type] = ''Officer'' > > > > > > > #somehow update with Officer-based validations > > > > > > > self > > > > > > > end > > > > > > > > #technically, this does nothing > > > > > > > def turn_to_person > > ... > > read more »--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---