ruby-on-rails - Rails 3 - 如何...在数据库列字段数据中存储非结构化数据

标签 ruby-on-rails ruby-on-rails-3

我想学习在 DATA 字段中存储非结构化数据的智能方法

例如,如果我有带有字段 id | 的表 AuditLog型号名称 |数据

在数据中,我想存储根据模型名称更改的各种类型的数据。我还希望它在数据中,以便出于性能原因我可以不使用 JOIN 输出这些记录。

示例 1 |照片 | {照片ID:1,照片名称:“blah”} 1 |评论 | {评论:1,评论内容:“blah”,parent_type:“照片”,parent_id:“1”}

关于如何输入和输出的建议?

谢谢

最佳答案

我不确定我是否正确理解了你的问题。但无论如何我都会尝试回答这个问题。

如果您需要将模型转换为 JSON,这非常简单。只需在模型上调用 .to_json 即可。然后您可以将其存储在 TEXT 列中。

要读回它,您有两种选择:

  • 读取 Ruby 哈希值:ActiveSupport::JSON.decode(some_json_text)

  • 将值作为对象读取 - 原始模型:获取上面获得的哈希并将其作为参数传递给 SomeModel.new。但在这种情况下你必须小心 - 关联的集合将不起作用,id将不会被设置,等等。

如何自定义行为有很多选项,但尚不清楚什么最适合您。我建议阅读此帮助页面:http://railsapi.com/doc/rails-v3.0.0/classes/ActiveModel/Serializers/JSON.html并根据需要定制您的解决方案。

在下面的示例中,我没有在模型上使用 .to_json 方法,因为示例中的方法更加可定制。例如,您可以控制关​​联的行为(是否将它们存储到日志中)等。阅读链接的文档您就会明白。

这里是示例实现(阅读里面的评论)

class AuditLog < ActiveRecord::Base

  #
  # Stores shallow snapshot (without nesting into associations) of current
  # model into the log in the JSON form
  #
  def self.audit(m)
    # encode passed model into the JSON text
    json = ActiveSupport::JSON.encode(m)
    # create new log record and store it to the database
    create(:model => m.class,
           :data => json)
  end

  #
  # Returns the logged item as a Ruby hash
  #
  # Your can access the result with ["attribute_name"]
  #
  def get_as_hash
    # get the hash
    result = ActiveSupport::JSON.decode(self.data)
    # normally the json is { model_name => { attributes ... } } and we want the
    # inner hash - so let's take it
    result.values.first
  end

  #
  # Returns the logged item as an original model (like Post, Comment, etc.)
  #
  # Beware that associations are filled only if they are stored in audit method
  # So in case of Post: post.comments will always return an empty array
  #
  def get_as_model
    # get hash
    hash = get_as_hash
    # create instance of the class model and pass the hash to init
    # attribute values
    m = self.model.constantize.new(hash)
    # the initializator above ignore :id so let's set it manually
    m.id = hash[:id]
    # return the model
    m
  end
end

你可以这样使用它:

class Post < ActiveRecord::Base
  has_many :comments

  # after any successful change store the model to log
  after_save :audit

  private

  # store the whole model to the log
  def audit
    AuditLog.audit(self)
  end
end

希望您会喜欢它!

关于ruby-on-rails - Rails 3 - 如何...在数据库列字段数据中存储非结构化数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3827851/

相关文章:

ruby-on-rails - Devise 注册后立即在 Controller 中执行某些操作

ruby-on-rails - Rails 4.2 ActiveSupport 错误

ruby-on-rails - 创建一个简单的 Rails 3 文本助手 Gem

ruby-on-rails - Rails - 如何访问当前环境的主机 URL?

ruby-on-rails - 在 Ruby on Rails 中创建动态页面

ruby-on-rails - 在 spree 中,是否有可能将所有结帐流程步骤保留在一个页面中?

ruby-on-rails - 使用 Ruby on Rails 的表单助手

ruby-on-rails - 更精确的 distance_of_time_in_words

ruby-on-rails - Rails actionmailer,gmail 有效,office 365 无效。

ruby-on-rails - UTF-8 问题中的 Rails ActiveRecord 无效字节序列