This seems like it must have been asked before - I really _did_ try to find it in the archives, so my apologies if it''s already out there. Utilizing ActiveRecord, I would like to specify a prefix for the column names in my table. For example, in ''Recipe 16 Integrating with Legacy Databases'' (Rails Recipes, from PragProg, by Fowler) they deal with integration with a WordPress db where all field names are preceded by "comment_" -- i.e. comment_author_email. The recipe explains how to deal with the primary key (comment_id) via: ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore which is great: the primary key would obviously be the most important piece to get working :) However, it stops short of going into detail on dealing with this on the other column names. I guess what I''m looking for is a nice clean way to take their extent their example - allowing me to reference the non-key fields as "author_email" instead of needing to always prefix and say things like "comment_author_email" all over my whole application. and since this will be in a more complete environment: I also don''t want to remove "comment_" from the front of every field name in the whole db! It will need to be specific to the Comment class itself. Any help is most appreciated. Thanks. - jim
Hello Jim,> However, it stops short of going into detail on dealing with this on > the other column names. > > I guess what I''m looking for is a nice clean way to take their extent > their example - allowing me to reference the non-key fields as > "author_email" instead of needing to always prefix and say things like > "comment_author_email" all over my whole application. and since this > will be in a more complete environment: I also don''t want to remove > "comment_" from the front of every field name in the whole db! It > will need to be specific to the Comment class itself.If I understand your problem correctly, let''s say we''ve got a Author model with a ''comment_author_email'' field in the associated table, and you want to do things like : a = Author.new a.author_email = ''...'' So you can use facade column ; in your model class Author < AR::B def author_email read_attribute("comment_author_email") end def author_email=(email) write_attribute("comment_author_email", email.to_s) end end and do the same for the other fields. Maybe a sort of model scaffolding will ease your job :) (one gotcha is the typecasting in the write_attribute call) My 2 (euro)cents, -- Jean-Fran?ois. -- Railsfrance - http://www.railsfrance.org
Jean-Fran?ois - Thanks for the help. Your example is just what I am
trying to do. However, I am now wondering if maybe I don''t have my
hands around exactly what is causing my issue...
For my exact application:
my field name is "user_email", which I would like to refer to as
"email". My table name is "common_users" and I have already
taken
care of it so that I can name my class "user".
I have the code (as you have detailed below) in my user.rb:
def email
read_attribute "user_email"
end
def email=(value)
write_attribute "user_email", value.to_s
end
however I run into the following method and see an error when
executing save (console output below the code)
def signup
return if generate_blank
@params[''user''].delete(''form'')
@user = User.new(@params[''user''])
begin
User.transaction(@user) do
@user.new_password = true
logger.warn "4444444444444444444444444444"
if @user.save
logger.warn "55555555555555555555555555555555"
#snip
end
logger.warn "66666666666666666666666666"
end
logger.warn "777777777777777777"
rescue
logger.warn "888888888888888888888"
flash.now[''message''] = l(:user_confirmation_email_error)
end
end
###############
console output::
User Columns (0.000580) SHOW FIELDS FROM common_users
SQL (0.000113) BEGIN
4444444444444444444444444444
User Load (0.000000) Mysql::Error: Unknown column
''common_users.email'' in ''where clause'':
SELECT * FROM common_users
WHERE (common_users.email = ''jimhalberg@gmail.com'') LIMIT 1
SQL (0.000109) ROLLBACK
888888888888888888888
The table name looks fine, but the field is still being referred to as
''email'' here. I guess I''m a bit confused as to why
these two
statements are running at all?
Again, thanks for the help in advance.
On 4/20/06, Jean-Fran?ois <jf.web3@gmail.com>
wrote:> Hello Jim,
>
> > However, it stops short of going into detail on dealing with this on
> > the other column names.
> >
> > I guess what I''m looking for is a nice clean way to take
their extent
> > their example - allowing me to reference the non-key fields as
> > "author_email" instead of needing to always prefix and say
things like
> > "comment_author_email" all over my whole application. and
since this
> > will be in a more complete environment: I also don''t want to
remove
> > "comment_" from the front of every field name in the whole
db! It
> > will need to be specific to the Comment class itself.
>
> If I understand your problem correctly, let''s say we''ve
got a Author model
> with a ''comment_author_email'' field in the associated
table, and
> you want to do things like :
>
> a = Author.new
> a.author_email = ''...''
>
> So you can use facade column ; in your model
>
> class Author < AR::B
> def author_email
> read_attribute("comment_author_email")
> end
>
> def author_email=(email)
> write_attribute("comment_author_email", email.to_s)
> end
> end
>
> and do the same for the other fields. Maybe a sort of model scaffolding
> will ease your job :) (one gotcha is the typecasting in the write_attribute
> call)
>
> My 2 (euro)cents,
>
> -- Jean-Fran?ois.
>
> --
> Railsfrance - http://www.railsfrance.org
>
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
>
>
--
http://jimhalberg.com
Jim :> Jean-Fran?ois - Thanks for the help. Your example is just what I am > trying to do. However, I am now wondering if maybe I don''t have my > hands around exactly what is causing my issue... > > For my exact application: > my field name is "user_email", which I would like to refer to as > "email". My table name is "common_users" and I have already taken > care of it so that I can name my class "user". > > I have the code (as you have detailed below) in my user.rb: > def email > read_attribute "user_email" > end > def email=(value) > write_attribute "user_email", value.to_s > end > > however I run into the following method and see an error when > executing save (console output below the code) > > def signup > return if generate_blank > @params[''user''].delete(''form'') > @user = User.new(@params[''user''])[...] In fact, I think there may be a problem with User#new when passing a hash, since the constructor creates the User instance with the help of the column definitions. As we''ve got a facade column (let''s say faked attribute), there must be trouble. The User#create must work correctly I think. You can check that by unit-testing your model. Test a User.new with a hash having a ''email'' key. If I''m right, it should fail. Instead, user = User.new user.new_password = ''...'' user.email = ''...'' user.save must work (another test) So test also User#create. For your code, maybe a way will be : h = params[:user] h.remove(''form'') email = h[:email] h.remove(:email) @user = User.new(h) @user.email = email ... And for convenience, make it a method class User < AR::B # maybe not a good idea to override AR::B#initialize def self.my_special_new(hash) email = hash[:email] hash.remove[:email] user = new(hash) user.email = email user end ... end sth like that... (to be unit-tested) Hope this helps, -- Jean-Fran?ois. -- ? la renverse.
I found the culprit... I had missed this guy hanging out in a cluster of validation lines: validates_uniqueness_of :email, :on => :create ... causing the execution of that select with the field name "email". Thanks a ton for the help on this Jean-Fran?ois. - Jim On 4/20/06, Jean-Fran?ois <jf.web3@gmail.com> wrote:> Jim : > > Jean-Fran?ois - Thanks for the help. Your example is just what I am > > trying to do. However, I am now wondering if maybe I don''t have my > > hands around exactly what is causing my issue... > > > > For my exact application: > > my field name is "user_email", which I would like to refer to as > > "email". My table name is "common_users" and I have already taken > > care of it so that I can name my class "user". > > > > I have the code (as you have detailed below) in my user.rb: > > def email > > read_attribute "user_email" > > end > > def email=(value) > > write_attribute "user_email", value.to_s > > end > > > > however I run into the following method and see an error when > > executing save (console output below the code) > > > > def signup > > return if generate_blank > > @params[''user''].delete(''form'') > > @user = User.new(@params[''user'']) > [...] > > In fact, I think there may be a problem with User#new > when passing a hash, since the constructor creates the User > instance with the help of the column definitions. As we''ve > got a facade column (let''s say faked attribute), there must be > trouble. The User#create must work correctly I think. > You can check that by unit-testing your model. Test a > User.new with a hash having a ''email'' key. > > If I''m right, it should fail. Instead, > > user = User.new > user.new_password = ''...'' > user.email = ''...'' > user.save > > must work (another test) > > So test also User#create. > > For your code, maybe a way will be : > > h = params[:user] > h.remove(''form'') > email = h[:email] > h.remove(:email) > @user = User.new(h) > @user.email = email > ... > > And for convenience, make it a method > > class User < AR::B > # maybe not a good idea to override AR::B#initialize > def self.my_special_new(hash) > email = hash[:email] > hash.remove[:email] > user = new(hash) > user.email = email > user > end > ... > end > > sth like that... (to be unit-tested) > > Hope this helps, > > -- Jean-Fran?ois. > > > -- > ? la renverse. >-- http://jimhalberg.com
Jim Halberg wrote:> This seems like it must have been asked before - I really _did_ try to > find it in the archives, so my apologies if it''s already out there. > > Utilizing ActiveRecord, I would like to specify a prefix for the > column names in my table. For example, in ''Recipe 16 Integrating with > Legacy Databases'' (Rails Recipes, from PragProg, by Fowler) they deal > with integration with a WordPress db where all field names are > preceded by "comment_" -- i.e. comment_author_email. > > The recipe explains how to deal with the primary key (comment_id) via: > ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore > > which is great: the primary key would obviously be the most important > piece to get working :) > > However, it stops short of going into detail on dealing with this on > the other column names. > > I guess what I''m looking for is a nice clean way to take their extent > their example - allowing me to reference the non-key fields as > "author_email" instead of needing to always prefix and say things like > "comment_author_email" all over my whole application. and since this > will be in a more complete environment: I also don''t want to remove > "comment_" from the front of every field name in the whole db! It > will need to be specific to the Comment class itself. > > Any help is most appreciated. Thanks. > - jimI did exactly just that for my presentation at Canada on Rails.. http://rubyurl.com/DRv -Robby