Reputation: 42602
I am using Rails v2.3.2.
I have a model:
class Cars < ActiveRecord::Base
tag_nr = rand(2007)
end
The Cars
model is mapped to the cars
table in database with columns name
, owner
.
As you see above, there is also a tag_nr
which is basically a random number.
I would like to have each instance object of Cars
class hold a random number generated like above. But I do not want to have this random number be stored in database. And in future, I can access this instance object's tag_nr
by:
nr = CAR_INSTANCE.tag_nr
And the nr
now is the same as the tag_nr
first generated for this Cars instance object.
So, where and how should I define this random number in my Car model?
-----------What I tried is:-----------
class Cars < ActiveRecord::Base
after_initialize :init
attr_accessor :tag_nr
def init
@tag_nr = rand(2007)
end
end
But if I retrieve a car from database and try to access tag_nr
, I got nil
:
@c=Cars.first
@c.tag_nr.nil? # it returns true
So, how can I have an model attribute(like tag_nr
) which is not persist in database as a table column but can be accessed as an attribute?
Upvotes: 1
Views: 1785
Reputation: 864
Shouldn't that be
class Cars < ActiveRecord::Base
after_initialize :init
attr_accessor :tag_nr
def init
self.tag_nr = rand(2007)
end
end
Example output from a Drug model (just because it was what I was working on at the time)
> d = Drug.first
=> #<Drug id: 1, name: "NSAIDs", category: "NSAID", comment: "Non-steroidal anti-inflammatory", created_at: "2011-11-23 17:46:22", updated_at: "2011-11-23 17:46:22">
> d.tag_nr
=> 1069
> d = Drug.last
=> #<Drug id: 6, name: "Antihypertensives", category: "ANTIHYPERTENSIVE", comment: "", created_at: "2011-11-23 17:46:22", updated_at: "2011-11-23 17:46:22">
> d.tag_nr
=> 1838
> d = Drug.first
=> #<Drug id: 1, name: "NSAIDs", category: "NSAID", comment: "Non-steroidal anti-inflammatory", created_at: "2011-11-23 17:46:22", updated_at: "2011-11-23 17:46:22">
> d.tag_nr
=> 800
There is nothing to stop a collision between the random numbers (ie two different instances could return the same number).
Upvotes: 0
Reputation: 8408
I suppose this task can't be solved. As I understand you want next: you have a Car in your DB and
car = Car.find(10)
car.tag_nr # assume this expression returns 100
... # some code here
other_car = Car.find(10)
car.tag_nr # this expression returns 100
correct?
if yes you have to pay more attention to =
operator which createc new object each time you use it you can check it with object_id
irb(main):074:0> "abs".object_id
=> 21413208
irb(main):075:0> "abs".object_id
=> 20742936
irb(main):076:0> a = "abs"
=> "abs"
irb(main):077:0> a.object_id
=> 21493488
irb(main):078:0> a = "abs"
=> "abs"
irb(main):079:0> a.object_id
=> 21172272
since all objects are different they have different values for instance variables
Upvotes: 0
Reputation: 27747
The problem with what you need is in the part where you say you want to be able to access the same random number over and over again.
You're asking for this number to persist, even though you're wanting to not store it in the database...
Either information persists... or it doesn't. Information that persists must be stored somewhere. Currently your persistent data is stored in the database.
You can see the problem here, I hope.
Any number you generate will last only so long as the object lasts... ie for the duration of a single request/response... and then it will disappear, because you are not persisting it in the place where data is persisted (the database).
If single-response duration is all that's need, then the solutions already offered here are the best you can get.
The alternatives are:
Upvotes: 4
Reputation: 650
Try this:
class Cars < ActiveRecord::Base
extend ActiveSupport::Memoizable
def tag_nr
rand(2007)
end
memoize :tag_nr
end
from: http://rails-bestpractices.com/posts/59-use-memoization
Upvotes: 2