From: Brian Candler Date: 2010-09-04T18:35:38+09:00 Subject: Re: Read cookie P奪l Bergstr旦m wrote: >> The value displayed (which is the value in the cookie) is the timestamp >> of the previous request. > > But that's in the controller. Or do I miss something? Yes, it's in the controller. > One more time: > > 1) I have a Rails app. > > 2) I have/had certain data aes encrypted in certain columns in mysql > with a unique key for each user. That key is saved in a cookie. If they > use an iPhone or another browser they need to ad the key to each > browser. It's just another layer of security on top of Rails. So if > someone get hold of that key it's useless unless you login or break the > security of mysql. > > 3) l use "before_save" and "fast-aes" in the model. So everything happes > in the model and in a script for encrypting located in /lib, just > because I can't get the cookie into the model with rails > cookies[:my_cookie]. Or can I? Maybe I'm overlooking something. Can get > the value of a cookie from the controller into the model in a simple > uniform way? Ah right, so now you're definitely asking a Rails question. I think your question is: how can I access request/controller parameters from an instance of the model? The brief answer is: you can't. An instance of a model exists independently of any controller. A model can be instantiated outside of a controller; and in principle, one model object could be shared between multiple controller instances. A simple solution is to pass the parameter explicitly. That is, in your model you can have a method which accepts the encryption key as a parameter, like 'decrypt' say, and invoke it from the controller: # code in controller ... thing = Thing.find(id) thing.decrypt(cookies["key"]) ... Or you could set an instance variable in the model (models can have regular Ruby attrs, which are not stored in the database), which in turn you can use in your before_save method. If you want to make it completely transparent, there is a messy solution you could consider, which is to use Thread-local variables. In your controller's "before" filter, do Thread[:key] = cookies["key"] Then this will be accessible in your model as Thread[:key]. You need to be very careful to reset this variable before *every* controller action, otherwise the key may leak from one user's request to another user. This is actually how Rails deals with timezones - in the controller, if you set Time.zone = xxx in the controller, it affects the model through a thread-local variable. See http://api.rubyonrails.org/classes/Time.html#method-c-zone%3D and click on "show source". I'd recommend you avoid doing this if you possibly can. I think in your case, I'd use an instance variable. class MyModel < ActiveRecord::Base attr_accessor :key def before_save raise "Key not set!" unless key ... encrypt using key end end class MyController < ApplicationController def create @thing = MyModel.new(params[:thing]) @thing.key = cookies[:key] @thing.save! end end Of course, you do need to update your code at each point where you load or save models, but there is no risk of one user's key hanging over to another request. This of course a 100% Rails question. If you didn't get a good answer on a Rails forum, maybe you needed to be bit clearer in the phrasing of your question. There is good advice at http://www.catb.org/~esr/faqs/smart-questions.html#intro In future I'd recommend you be more specific about what you're trying to do; post samples of code; and mark the points where you're having problems. One ambiguous sentence just doesn't cut it, and most people are likely to skip over it. HTH, Brian. -- Posted via http://www.ruby-forum.com/.