一种将模型属性作为表列不在数据库中持久化的方法

时间:2011-12-14 11:22:52

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1

我正在使用 Rails v2.3.2

我有一个模特:

class Cars < ActiveRecord::Base

  tag_nr = rand(2007)

end

Cars模型已映射到数据库中的cars表,列nameowner

如上所述,还有tag_nr基本上是随机数

我希望Cars 的每个实例对象持有如上所述生成的随机数我不希望将此随机数存储在数据库中。将来,我可以通过:

访问此实例对象的tag_nr
nr = CAR_INSTANCE.tag_nr

nr现在与首次为此Cars实例对象生成的tag_nr 相同

那么,我应该在哪里以及如何在我的Car模型中定义这个随机数?

-----------我尝试的是:-----------

class Cars < ActiveRecord::Base
  after_initialize :init

  attr_accessor :tag_nr

  def init
    @tag_nr = rand(2007)
  end
end  

但如果我从数据库中检索汽车并尝试访问tag_nr,我就会nil

@c=Cars.first
@c.tag_nr.nil? # it returns true

那么,我怎样才能拥有一个模型属性(如tag_nr),它不作为表列在数据库中持久化,但可以作为属性进行访问?

4 个答案:

答案 0 :(得分:4)

您需要的问题在于您希望能够一遍又一遍地访问相同随机数的部分。

即使您希望将其存储在数据库中,您仍然要求此号码继续存在...

信息仍然存在......或者它没有。持续存在的信息必须存储在某处。目前,您的持久数据存储在数据库中。

我希望你能在这里看到问题。

您生成的任何数字只会持续只要对象持续...即单个请求/响应的持续时间......然后它将消失,因为您没有将数据保持在数据所在的位置坚持(数据库)。

如果单一响应持续时间是您所需要的,那么此处提供的解决方案是您可以获得的最佳解决方案。

替代方案是:

  1. 将其存储在数据库中(这是唯一可以确定的方法)
  2. 在一个独特且不可更改的方面找到一些散列方法 模型中的数据。例如,在记录上运行MD5或SHA1 id + created_at timestamp

答案 1 :(得分:2)

试试这个:

class Cars < ActiveRecord::Base
  extend ActiveSupport::Memoizable

  def tag_nr
    rand(2007)
  end
  memoize :tag_nr
end

来自:http://rails-bestpractices.com/posts/59-use-memoization

答案 2 :(得分:0)

不应该是

class Cars < ActiveRecord::Base
  after_initialize :init

  attr_accessor :tag_nr

  def init
    self.tag_nr = rand(2007)
  end
end

药物模型的示例输出(仅仅因为它是我当时的工作)

> 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

没有什么可以阻止随机数之间的碰撞(即两个不同的实例可以返回相同的数字)。

答案 3 :(得分:0)

我认为这个任务无法解决。据我所知你接下来想要的是:你的数据库中有一辆汽车和

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

正确?

如果是,您必须更加关注每次使用时创建新对象的=运算符,您可以使用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

由于所有对象都不同,因此它们具有不同的实例变量值