I''ve just written some code to extend ActiveRecord to add created_by and updated_by. Details are here: http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/ I''d welcome any opinions on whether this is the best way to go about it, and if there are any potential improvements that could be made? At the moment, if there is no logged in user, then it will generate SQL errors if the database fields are set as NOT NULL (as the fields will be nil). I suppose that''s the best way to model it anyway, as if it''s possible to add items without being logged in then those fields should be set as NULL (and not 0 or something). Thanks. -- R.Livsey http://livsey.org
On 7/16/05, Richard Livsey <richard-gfRugNUWsoQdnm+yROfE0A@public.gmane.org> wrote:> I''ve just written some code to extend ActiveRecord to add created_by and > updated_by. > > Details are here: > http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/Nice stuff Richard. I especially like the use of cattr_accessors for the current_user. Very clean. -- Cheers Koz
On 7/15/05, Richard Livsey <richard-gfRugNUWsoQdnm+yROfE0A@public.gmane.org> wrote:> I''ve just written some code to extend ActiveRecord to add created_by and > updated_by.Perhaps I''m a bit dense, but how does this differ from simply doing a "belongs_to :author" in your model and then having "author_id" column in your table? From my limited understanding, all you''ve done is renamed "author_id" into "created_by" and made the "belongs_to :author" macro implicit. -- Urban Artography http://artography.ath.cx
> [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] Namens Rob Park > On 7/15/05, Richard Livsey <richard-gfRugNUWsoQdnm+yROfE0A@public.gmane.org> wrote: > > I''ve just written some code to extend ActiveRecord to add > created_by > > and updated_by. > > Perhaps I''m a bit dense, but how does this differ from simply > doing a "belongs_to :author" in your model and then having > "author_id" column in your table? From my limited > understanding, all you''ve done is renamed "author_id" into > "created_by" and made the "belongs_to :author" macro implicit.The main reasening behind created_by/updated_by would be they automaticly get filled in when creating/updating entries. So if I have a user logged in and he creates something, then created_by gets filled in automaticly by the user_id of that logged in person. That way you can very easily track who created/modified your objects in the database. --- Jeroen Janssen
> [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] Namens Richard Livsey > > I''ve just written some code to extend ActiveRecord to add > created_by and updated_by. > > Details are here: > http://livsey.org/2005/07/16/adding_created_by_and_updated_by_ > to_rails/ > > I''d welcome any opinions on whether this is the best way to > go about it, and if there are any potential improvements that > could be made?Hi, this looks good to me, except for "Hardcoding" the User model into it. Is something like this possible: class TheThingUserCreate < ActiveRecord::Base relates_to_user_in :users end You would need to create a "relates_to_user_in" method that interacts with created_by/updated_by to use the correct User table. Now the only thing ''left'' would be the assumption that the User class contains current_user (but I don''t know if that is such a problem). --- Jeroen Janssen
Richard Livsey <richard@...> writes:> > I''ve just written some code to extend ActiveRecord to add created_by and > updated_by. > > Details are here: > http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/ > > I''d welcome any opinions on whether this is the best way to go about it, > and if there are any potential improvements that could be made? > > At the moment, if there is no logged in user, then it will generate SQL > errors if the database fields are set as NOT NULL (as the fields will be > nil). I suppose that''s the best way to model it anyway, as if it''s > possible to add items without being logged in then those fields should > be set as NULL (and not 0 or something). > > Thanks.Cool! I really love automagic code! Please add it to the howto section of the rubyonrails wiki. Some remarks; According to pickaxe2 "included" is prefered over "append_features" since ruby 1.8. Another thing, I don''t understand why in the create method you use "[]=" to set properties and in update "write_attribute", according to activerecord rdoc the first is a alias for the latter, bit confusing to the reader. And, I agree with Jeroen, you could make it more generic by not hardwiring the User model. Remco
Jeroen Janssen wrote:>>[mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] Namens Richard Livsey >>Details are here: >>http://livsey.org/2005/07/16/adding_created_by_and_updated_by_ >>to_rails/ >> >> >> >Hi, this looks good to me, except for "Hardcoding" the User model into it. > >Is something like this possible: > >class TheThingUserCreate < ActiveRecord::Base > relates_to_user_in :users >end > >You would need to create a "relates_to_user_in" method that interacts with >created_by/updated_by to use the correct User table. > >Thanks for the feedback. I like the idea of not hardcoding the User model in, but and not 100% clear on how this would work. Has anyone got any further details or some examples of how this works in other parts of rails? Thanks again. -- R.Livsey http://livsey.org
Remco van ''t Veer wrote:>Richard Livsey <richard@...> writes: > > >>Details are here: >>http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/ >> >> >Cool! I really love automagic code! Please add it to the howto section of the >rubyonrails wiki. > >Thanks, I''ll add it in today.>Some remarks; According to pickaxe2 "included" is prefered over >"append_features" since ruby 1.8. > >Ok. I was mainly following how Timestamp does it, but I''ll take a look and change that.>Another thing, I don''t understand why in the >create method you use "[]=" to set properties and in update "write_attribute", >according to activerecord rdoc the first is a alias for the latter, bit >confusing to the reader. > >I blame that on working on it at 3am! I was using write_attribute on the other parts too earlier but shifted to the []= method and must have missed that one. What would be the preferred way of doing it? Is there any benefits of write_attribute over []=?>And, I agree with Jeroen, you could make it more >generic by not hardwiring the User model. > >I''ll definately get that done as soon as I can fiugure out how to go about it! Thanks for the feedback, I''ll update the code asap and hopefully it''ll be usefull for other people. -- R.Livsey http://livsey.org
Jeroen Janssen wrote:>Hi, this looks good to me, except for "Hardcoding" the User model into it. > >Is something like this possible: > >class TheThingUserCreate < ActiveRecord::Base > relates_to_user_in :users >end > >This now works exactly as you describe! I''ve updated the blog post [1] and the wiki page [2] with more details.>Now the only thing ''left'' would be the assumption that the User class >contains current_user (but I don''t know if that is such a problem). > > >I agree. Not sure how to get round that though. It''s not a bad convention to force on people though IMHO. Thanks for the help! [1] http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/ [2] http://wiki.rubyonrails.com/rails/show/Howto+Add+created_by+and+updated_by -- R.Livsey http://livsey.org
Richard, This looks very nice -- thanks for posting it. I have a number of db tables that already had created_by and updated_by columns that I hadn''t implemented yet, so this is very timely. :) I hadn''t thought of this route -- extending ActiveRecord. I''d been thinking more of making a base AR class, something like ''Auditable'' and extending that for the objects with these columns. I''m wondering if in general I''m stuck in Java developer mode and this is a more Ruby/Rails idiom? Or would people also consider the inheritance route? I guess I do tend to see more composition in rails in general, and I''m familiar with (and agree with) the ''prefer composition'' theory of object modeling. But in a way this seems a little hairy -- getting into ActiveRecord itself.... On a more pragmatic front, I''m having trouble with the User model knowing the current user. I keep the user_id in the session and would like to use that. But accessing the session from a model is supposed to be avoided, isn''t it? Is there a proper way I should go about transferring the session contents to my user model? Thanks! Tom -- Tom Wilcoxen http://convergentarts.com http://www.dreamhost.com/r.cgi?twilcoxen _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
> I hadn''t thought of this route -- extending ActiveRecord. I''d been thinking > more of making a base AR class, something like ''Auditable'' and extending > that for the objects with these columns. I''m wondering if in general I''m > stuck in Java developer mode and this is a more Ruby/Rails idiom? Or would > people also consider the inheritance route? I guess I do tend to see more > composition in rails in general, and I''m familiar with (and agree with) the > ''prefer composition'' theory of object modeling. But in a way this seems a > little hairy -- getting into ActiveRecord itself....The problem with inheritance in ActiveRecord (at least in your expected usage of it), is it assumes Single Table Inheritance (http://rails.rubyonrails.com/classes/ActiveRecord/Base.html). So yes, Richard''s mixin is the ''rails'' way to extend AR functionality. -- rick http://techno-weenie.net
> [mailto:rails-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] Namens Richard Livsey > >Now the only thing ''left'' would be the assumption that the > User class > >contains current_user (but I don''t know if that is such a problem). > > > I agree. Not sure how to get round that though. > It''s not a bad convention to force on people though IMHO.Hi, I''ve been thinking about this, and I think I agree with Tom that the current user should be stored in a session somehow. If you store it in the model (as we''re currently doing), what then happens when two people try to login at the same time? -- Jeroen Janssen
Jeroen Janssen wrote:>Hi, I''ve been thinking about this, and I think I agree with Tom that the >current user should be stored in a session somehow. > >If you store it in the model (as we''re currently doing), what then happens >when two people try to login at the same time? > >I could be misunderstanding the problem, but here''s what I''m doing: In my User model I have a method called current_user which simply returns the user from the session. I only store the user ID in the session and User.current_user grabs that and returns the right user. So It''s still being stored in the session. This also means you can use User.current_user in lots of places and if you change how the current user is stored (whole obj in session, just the ID, some other way) then you just change how current_user works. DRY in action. I notice that Michael Koziarski wrote something about this on his blog: http://www.koziarski.net/archives/2005/07/16/environment -- R.Livsey http://livsey.org
On Jul 16, 2005, at 2:35 PM, Richard Livsey wrote:> Jeroen Janssen wrote: >> Hi, this looks good to me, except for "Hardcoding" the User model >> into it. >> >> Is something like this possible: >> >> class TheThingUserCreate < ActiveRecord::Base >> relates_to_user_in :users >> end >> >> > This now works exactly as you describe! > I''ve updated the blog post [1] and the wiki page [2] with more > details.This is probably my fault, but it''s dying here. After implementing this, in a new user signup I get: empty symbol string /lib/usermonitor.rb:79:in `const_get'' /lib/usermonitor.rb:79:in `user_model'' /lib/usermonitor.rb:17:in `create'' app/controllers/user_controller.rb:35:in `signup'' app/controllers/user_controller.rb:33:in `transaction'' app/controllers/user_controller.rb:33:in `signup'' script/server:49 Sprinkling some debug statements in, it appears that the error here: Object.const_get(self.user_model_name.to_s.singularize.humanize) is that it''s not really calling self.user_model_name... ?? If I put a logger.info("blahblahblah") in that method (self.user_model_name), it never gets logged out anywhere, so is it not getting called, or is the logger just not valid in that context?
Steven Palm wrote:> This is probably my fault, but it''s dying here. After implementing > this, in a new user signup I get: > > empty symbol string > > /lib/usermonitor.rb:79:in `const_get'' > /lib/usermonitor.rb:79:in `user_model'' > /lib/usermonitor.rb:17:in `create'' > app/controllers/user_controller.rb:35:in `signup'' > app/controllers/user_controller.rb:33:in `transaction'' > app/controllers/user_controller.rb:33:in `signup'' > script/server:49 > > Sprinkling some debug statements in, it appears that the error here: > > Object.const_get(self.user_model_name.to_s.singularize.humanize) > > is that it''s not really calling self.user_model_name... ?? > > If I put a logger.info("blahblahblah") in that method > (self.user_model_name), it never gets logged out anywhere, so is it > not getting called, or is the logger just not valid in that context?Hmm odd. Any chance sending me a copy of the files in question (the user model and whatever else). I''ll take a look this evening and see if I can work it out. Thanks. -- R.Livsey http://livsey.org
Im alos having the exact same problem. Have you found and solution to this already? 2005/7/20, Richard Livsey <richard-gfRugNUWsoQdnm+yROfE0A@public.gmane.org>:> > > Steven Palm wrote: > > > This is probably my fault, but it''s dying here. After implementing > > this, in a new user signup I get: > > > > empty symbol string > > > > /lib/usermonitor.rb:79:in `const_get'' > > /lib/usermonitor.rb:79:in `user_model'' > > /lib/usermonitor.rb:17:in `create'' > > app/controllers/user_controller.rb:35:in `signup'' > > app/controllers/user_controller.rb:33:in `transaction'' > > app/controllers/user_controller.rb:33:in `signup'' > > script/server:49 > > > > Sprinkling some debug statements in, it appears that the error here: > > > > Object.const_get(self.user_model_name.to_s.singularize.humanize) > > > > is that it''s not really calling self.user_model_name... ?? > > > > If I put a logger.info("blahblahblah") in that method > > (self.user_model_name), it never gets logged out anywhere, so is it > > not getting called, or is the logger just not valid in that context? > > > Hmm odd. > > Any chance sending me a copy of the files in question (the user model > and whatever else). I''ll take a look this evening and see if I can work > it out. > > Thanks. > > -- > R.Livsey > http://livsey.org > > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Giovanni Degani tiefox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org ICQ 965609 _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
I''m just now installing the created_by/updated_by implementation and I''m running into this error. Does anyone have a solution for this? I can''t find one anywhere and my ruby debugging skills are exhausted. Thanks, david On 8/22/05, Giovanni Degani <tiefox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Im alos having the exact same problem. > Have you found and solution to this already? > > 2005/7/20, Richard Livsey <richard-gfRugNUWsoQdnm+yROfE0A@public.gmane.org>: > > > > Steven Palm wrote: > > > > > This is probably my fault, but it''s dying here. After implementing > > > this, in a new user signup I get: > > > > > > empty symbol string > > > > > > /lib/usermonitor.rb:79:in `const_get'' > > > /lib/usermonitor.rb:79:in `user_model'' > > > /lib/usermonitor.rb:17:in `create'' > > > app/controllers/user_controller.rb:35:in `signup'' > > > app/controllers/user_controller.rb:33:in `transaction'' > > > app/controllers/user_controller.rb:33:in `signup'' > > > script/server:49 > > > > > > Sprinkling some debug statements in, it appears that the error here: > > > > > > > Object.const_get(self.user_model_name.to_s.singularize.humanize) > > > > > > is that it''s not really calling self.user_model_name... ?? > > > > > > If I put a logger.info("blahblahblah") in that method > > > (self.user_model_name), it never gets logged out anywhere, so is it > > > not getting called, or is the logger just not valid in that context? > > > > > > Hmm odd. > > > > Any chance sending me a copy of the files in question (the user model > > and whatever else). I''ll take a look this evening and see if I can work > > it out. > > > > Thanks. > > > > -- > > R.Livsey > > http://livsey.org > > > > > > > > _______________________________________________ > > Rails mailing list > > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > > > -- > Giovanni Degani > tiefox-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org > ICQ 965609 > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >