Ruby on rails 从Json创建ActiveRecord实例

Ruby on rails 从Json创建ActiveRecord实例,ruby-on-rails,caching,activerecord,Ruby On Rails,Caching,Activerecord,在不触发任何数据库操作的情况下创建新的Ruby/Rails对象的最佳方法是什么 例如,如果我有一个任务类 class Task < ActiveRecord::Base has_many :tags has_one :location end 我想重建对象,但不触发任何数据库交互 @task = Task.new @task.id = task_json['id'] @task.title = task_json['title'] @task.location = Locati

在不触发任何数据库操作的情况下创建新的Ruby/Rails对象的最佳方法是什么

例如,如果我有一个任务类

class Task < ActiveRecord::Base
  has_many :tags
  has_one :location

end
我想重建对象,但不触发任何数据库交互

@task = Task.new
@task.id = task_json['id']
@task.title = task_json['title']
@task.location = Location.new(:lat => task_json['location']['lat'], :lon => task_json['location']['lon'])

@task.tags = ...

理想情况下,一旦构建对象,就不可能以任何方式进行保存或数据库交互。

您可以尝试在JSON字符串
task\u JSON上使用
JSON.parse
,方法如下:

task = Task.new(JSON.parse(task_json))
在不触发任何数据库操作的情况下创建新的Ruby/Rails对象的最佳方法是什么

例如,如果我有一个任务类

class Task < ActiveRecord::Base
  has_many :tags
  has_one :location

end
class任务

普通的旧Ruby对象 如果您想要一个不持久的PORO(普通的旧Ruby对象),为什么还要使用子类
ActiveRecord::Base
?您可以将其放入任何自动加载路径,如
app/models/task.rb

class Task
  attr_reader :tags, :location, ...
  def initialize(...)
    @tags = ...
    @location = ...
    ...
  end
end
然后在其他地方创建它,如:

task = Task.new(...)
然后您可以访问其部分,如:

task.tags
在这里,您可以传递已解析的JSON、JSON字符串、args等

但是,
JSON.parse(一些JSON\u字符串)
中的散列本身是一个Ruby对象,因此您可以同样轻松地使用它。它也不会触发任何数据库操作。:)您可能使用类任务的主要原因是为了让它更清楚地知道它是什么,以及期望从中得到什么,但是哈希也很容易处理。看情况而定

如果你真的想要一个只读的ActiveRecord模型,你可以使用其中的一个。我写了一篇文章,其他一些人也参与了调用,但是您需要这样做的时间应该很少,而且它更倾向于从数据库读取数据,然后尝试不允许通过该模型对特定表进行数据库更新

仅在从JSON创建时使ActiveRecord模型实例只读 在你的评论中,你说如果我理解正确的话,你只想在从缓存中提取时将其设置为只读

看看创业板是如何改变AR行为的:

我猜当您使用JSON散列初始化模型时,您会希望设置一个标志,类似的方法可以查看并在设置该标志时引发
ActiveRecord::ReadOnlyRecord
或类似的问题

但这仅保护在中使用这些方法的模型。如果您与其他模型有关联,则除非它们使用类似的方法,否则不会保护它们。最后,如果你一定要这样做的话,你可能会更好地使用POROs和常规AR模型


然而,这听起来似乎是一个痛苦的使用。我会避免任何让用户(或开发人员)抓挠他/她的头太多的事情。

我只希望当我从缓存加载json时,它会这样做。否则,我需要所有ActiveRecord功能。我们有很多时候从MySql读/写,但是为了提高搜索性能,列表项响应被缓存在json中(对于api和web)。我希望使用AR类,以便视图中的“render@task”可以与对象AR或PORO一起工作。我想我可以复制所有类并伪装它们以进行渲染,但我不想这么做。还有一件事,你说“但是为了提高搜索性能,列表项响应缓存在json中”。AR已经缓存,如果您有性能问题,您是在执行n+1查询还是使用
进行优化,包括:
、索引、额外的数据库优化、在Web服务器级别缓存响应、差异服务器/服务器优化、减少客户端呼叫等?我们获得了大量流量。列表中的项有很多子对象/嵌套对象。即使包含子对象,缓存结果也很有帮助。我们目前将html缓存在memcache中,但我对缓存json感兴趣,这样它就可以被api(iphone、android、windows)和web应用程序使用。我想我找到了一种避免触发DB操作的方法-通过调用task[:location]=location.new和task[:tags]如果是我,我将分离提供读写和只读数据的服务/操作。同时使用两者可能会让其他开发人员感到困惑,并且可能更容易产生支持问题。顺便说一句,我是你公司/网站的超级粉丝。定期使用它。非常好的信息。json响应不是对象的精确表示,因此这并不完美,但我可以做一些。如果它不是精确表示,恐怕您必须手动构建对象。除非有另一种我不知道的方法,否则我会得到一个
ActiveModel::MassAssignmentSecurity::Error:不能批量分配受保护的属性:created_at,id…。
我如何解决这个问题?你可以将第二个参数传递给.new
task=task.new(JSON.parse(task_JSON),而没有保护:true)
有关可用于解决
受保护属性问题的自定义
from_json
方法,请参阅