简体   繁体   English

现有 Rails model 未从数据库中获取

[英]Existing Rails model without fetching it from the database

Does anyone know if its possible to create a model instance and apply the ID and any other attributes without having to load it from the database?有谁知道是否可以创建一个 model 实例并应用 ID 和任何其他属性而无需从数据库加载它? I tried doing this, but the associations are not fetched from the database:( Any ideas?我试过这样做,但没有从数据库中获取关联:(有什么想法吗?


EDIT编辑

What I want to accomplish is simply this:我想要完成的只是这样:

  1. Fetch an existing record from the database.从数据库中获取现有记录。
  2. Store as "hashed" output of the record into redis or some other memory store.将记录的“散列”output 存储到 redis 或其他一些 memory 存储中。
  3. Next time when that record is fetched, fetch the cached store first and if it is not found then goto step 1.下次获取该记录时,首先获取缓存的存储,如果未找到,则转到步骤 1。
  4. If there is a cache hit, then load all the cached attributes into that model and make that model instance behave as if it were a model fetched from the database with a finite set of columns.如果有缓存命中,则将所有缓存的属性加载到 model 中,并使 model 实例表现得好像它是从数据库中提取的有限列集的 model 一样。

This is where I am stuck, what I've been doing is creating a Model.new object and setting each of the params manually.这就是我卡住的地方,我一直在做的是创建一个 Model.new object 并手动设置每个参数。 This works, but it treats the instantiated model object as a new record.这可行,但它将实例化的 model object 视为新记录。 There has got to be an intermediate subroutine in ActiveRecord that does the attribute setting. ActiveRecord 中必须有一个中间子程序来进行属性设置。

I solved the problem by doing the following.我通过执行以下操作解决了这个问题。

  1. Create a new model class which extends the model class that I want to have cached into memory. Create a new model class which extends the model class that I want to have cached into memory.

  2. Set the table_name of the new class to the same one as the parent class.将新 class 的 table_name 设置为与父 class 相同的名称。

  3. Create a new initialize method, call the super method in it, and then allow a parameter of that method to allow for a hash variable containing all the properties of the parent class.创建一个新的初始化方法,在其中调用超级方法,然后允许该方法的参数允许包含父 class 的所有属性的 hash 变量。

  4. Overload the method new_record?重载方法new_record? and set that to false so that the associations work.并将其设置为false以便关联工作。

Here's my code:这是我的代码:

class Session < User

  self.table_name = 'users'

  METHODS = [:id, :username] # all the columns that you wish to have in the memory hash
  METHODS.each do |method|
    attr_accessor method
  end

  def initialize(data)
    super({})

    if data.is_a?(User)
      user = data
      data = {}
      METHODS.each do |key|
        data[key] = user.send(key)
      end
    else
      data = JSON.parse(data)
    end

    data.each do |key,value|
      key = key.to_s
      self.send(key+'=',value)
    end
  end

  def new_record?
    false
  end

end

The memcached gem will allow you to shove arbitrary Ruby objects into it. memcached gem 将允许您将任意 Ruby 对象推入其中。 This should all get handled for you transparently, if you're using it.如果您正在使用它,这一切都应该透明地为您处理。

Otherwise, take a look at ActiveRecord::Base#instantiate to see how it's done normally.否则,看看 ActiveRecord::Base#instantiate 看看它是如何正常完成的。 You're going to have to trace through a bunch of rails stack, but that's what you get for attempting such hackery!您将不得不通过一堆 Rails 堆栈进行跟踪,但这就是您尝试这种骇客所得到的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM