Chris
2009-Jun-08 21:44 UTC
DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
As part of my project, I need to store IP address for every object that was created. User Topic Payment and more... Now all these records have the following attribute in their table called "ip_address_on_create". One way to do this is to put this code everywhere in the controllers: user.ip_address_on_create = request.remote_ip ,.... and so forth. Now to conform to DRY (don''t repeat yourself), I see the mechanism: after_create (model) and after_filter ( controller). I am not really sure how to tie this thing together. Would appreciate any tips or Ruby-Fu . Thanks in advance! Chris
pharrington
2009-Jun-08 23:45 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
I haven''t tested this at all, and to be quit honest it feels a bit hackish, but the following comes to mind: before_filter lambda { params.merge! :ip_address_on_create => request.remote_ip } Add the appropriate attribute to attr_accessible and you''ll be good to go. On Jun 8, 5:44 pm, Chris <chrisn...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> As part of my project, I need to store IP address for every object > that was created. > > User > Topic > Payment > and more... > > Now all these records have the following attribute in their table > called "ip_address_on_create". > > One way to do this is to put this code everywhere in the controllers: > > user.ip_address_on_create = request.remote_ip ,.... and so > forth. > > Now to conform to DRY (don''t repeat yourself), I see the mechanism: > after_create (model) and after_filter ( controller). I am not > really sure how to tie this thing together. Would appreciate any tips > or Ruby-Fu . > > Thanks in advance! > Chris
pharrington
2009-Jun-08 23:47 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
or rather you''re more likely going to be doing params[:user].merge!... but you get the idea On Jun 8, 7:45 pm, pharrington <xenogene...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I haven''t tested this at all, and to be quit honest it feels a bit > hackish, but the following comes to mind: > > before_filter lambda { params.merge! :ip_address_on_create => > request.remote_ip } > > Add the appropriate attribute to attr_accessible and you''ll be good to > go. > > On Jun 8, 5:44 pm, Chris <chrisn...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > As part of my project, I need to store IP address for every object > > that was created. > > > User > > Topic > > Payment > > and more... > > > Now all these records have the following attribute in their table > > called "ip_address_on_create". > > > One way to do this is to put this code everywhere in the controllers: > > > user.ip_address_on_create = request.remote_ip ,.... and so > > forth. > > > Now to conform to DRY (don''t repeat yourself), I see the mechanism: > > after_create (model) and after_filter ( controller). I am not > > really sure how to tie this thing together. Would appreciate any tips > > or Ruby-Fu . > > > Thanks in advance! > > Chris > >
Colin Law
2009-Jun-09 07:36 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
2009/6/8 Chris <chrisnow7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:> > As part of my project, I need to store IP address for every object > that was created. > > User > Topic > Payment > and more... > > Now all these records have the following attribute in their table > called "ip_address_on_create". > > One way to do this is to put this code everywhere in the controllers: > > user.ip_address_on_create = request.remote_ip ,.... and so > forth. > > > Now to conform to DRY (don''t repeat yourself), I see the mechanism: > after_create (model) and after_filter ( controller). I am not > really sure how to tie this thing together. Would appreciate any tips > or Ruby-Fu . >Might the DRYest way to do this be to use a polymorphic association for the IP address? Colin
Mukund
2009-Jun-09 10:41 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
Have a look at active_record::observers and wrap the save method with an update to the ip address. Declare a class level variable in application.rb with a before_filter that populates the IP into the variable (and subsequently used by the observer). On Jun 9, 2:44 am, Chris <chrisn...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> As part of my project, I need to store IP address for every object > that was created. > > User > Topic > Payment > and more... > > Now all these records have the following attribute in their table > called "ip_address_on_create". > > One way to do this is to put this code everywhere in the controllers: > > user.ip_address_on_create = request.remote_ip ,.... and so > forth. > > Now to conform to DRY (don''t repeat yourself), I see the mechanism: > after_create (model) and after_filter ( controller). I am not > really sure how to tie this thing together. Would appreciate any tips > or Ruby-Fu . > > Thanks in advance! > Chris
Jodi Showers
2009-Jun-10 14:48 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
Makund - it is quite likely that your solution will break when multithreading arrives (as will will loads of other stuff) On 9-Jun-09, at 6:41 AM, Mukund wrote:> > Have a look at active_record::observers and wrap the save method with > an update to the ip address. Declare a class level variable in > application.rb with a before_filter that populates the IP into the > variable (and subsequently used by the observer). > > > > On Jun 9, 2:44 am, Chris <chrisn...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> As part of my project, I need to store IP address for every object >> that was created. >> >> User >> Topic >> Payment >> and more... >> >> Now all these records have the following attribute in their table >> called "ip_address_on_create". >> >> One way to do this is to put this code everywhere in the controllers: >> >> user.ip_address_on_create = request.remote_ip ,.... and so >> forth. >> >> Now to conform to DRY (don''t repeat yourself), I see the mechanism: >> after_create (model) and after_filter ( controller). I am not >> really sure how to tie this thing together. Would appreciate any tips >> or Ruby-Fu . >> >> Thanks in advance! >> Chris > >
Colin Law
2009-Jun-10 21:05 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
009/6/10 Jodi Showers <jodi-BOB1p6JRLoAV+D8aMU/kSg@public.gmane.org>:> > Makund - it is quite likely that your solution will break when > multithreading arrives (as will will loads of other stuff)Could you explain why please, for the uninitiated? Thanks Colin
pharrington
2009-Jun-10 21:44 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
Basically... the class variable is shared by all instances of the controller in question spawned by the Rack server process. Multithreaded Rails handles multiple requests simultaneously, and thus multiple simultaneous instances of the controller. Two requests come along, one from 1.1.1.1, then one from 2.2.2.2 immediately after. before_filter from 1.1.1.1''s controller instance sets class variable accordingly, then before_filter from 2.2.2.2''s instance overwrites the variable. Controller instance from 1.1.1.1 now uses 2.2.2.2''s IP, and shinanagins ensue. On Jun 10, 5:05 pm, Colin Law <clan...-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:> 009/6/10 Jodi Showers <j...-BOB1p6JRLoAV+D8aMU/kSg@public.gmane.org>: > > > > > Makund - it is quite likely that your solution will break when > > multithreading arrives (as will will loads of other stuff) > > Could you explain why please, for the uninitiated? > Thanks > Colin
hoenth
2009-Jun-11 02:37 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
> > > > Makund - it is quite likely that your solution will break when > > > multithreading arrives (as will will loads of other stuff) >You could try using Thread.current in your model when storing your class variable. For example, in your User model, you could have the following methods: def self.ip_address=(ip_address) Thread.current[:ip_address] = ip_address end def self.ip_address Thread.current[:ip_address] end You would set these as part of your authentication process User.ip_address = request.remote_ip Then you might be able to use this in a :before_save filter in your models before_save :set_ip_address def set_ip_address self.ip_address = User.ip_address end
Fernando Perez
2009-Jun-11 06:22 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord o
> For example, in your User model, you could have the following methods: > > def self.ip_address=(ip_address) > Thread.current[:ip_address] = ip_address > end > > def self.ip_address > Thread.current[:ip_address] > endGod please tell me he did not suggest to use threads in order to add an argument. -- Posted via http://www.ruby-forum.com/.
Mukund
2009-Jun-11 10:30 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord object (to store IP address on every object created)
Replace the class variable with a method call instead? On Jun 10, 7:48 pm, Jodi Showers <j...-BOB1p6JRLoAV+D8aMU/kSg@public.gmane.org> wrote:> Makund - it is quite likely that your solution will break when > multithreading arrives (as will will loads of other stuff) >
hoenth
2009-Jun-11 13:19 UTC
Re: DRY (don''t repeat yourself) way / Hook to Activerecord o
> God please tell me he did not suggest to use threads in order to add an > argument. > -- > Posted viahttp://www.ruby-forum.com/.Here is a brief discussion on Thread.current used in class variables. http://coderrr.wordpress.com/2008/04/10/lets-stop-polluting-the-threadcurrent-hash/ As there is clearly debate about the robustness of using this method, I offer it only as a suggestion. It has worked for me.