【问题标题】:Organic Rails Data-Model with NoSQL Database使用 NoSQL 数据库的有机 Rails 数据模型
【发布时间】:2012-09-23 20:15:20
【问题描述】:

我想充分利用 NoSQL 文档的有机特性,构建一个动态数据模型,该模型可以增长、更改,并且对于大多数数据集都不同。下面是模型 SomeRequest.rb ,其中包含从 Couchbase 设置和获取的代码,但我无法让函数 addOrUpdate(key, value) 工作:

undefined method `each' for "0":String 

Completed 500 Internal Server
Error in 16ms NoMethodError (undefined method `each' for "0":String): 
config/initializers/quiet_assets.rb:7:in `call_with_quiet_assets'

是返回错误。有没有办法让这项工作,添加(或更新现有的)密钥,然后将文档保存到数据库中?

class SomeRequest < Couchbase::Model
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Callbacks
  extend ActiveModel::Naming

  # Couch Model
  define_model_callbacks :save

  attribute :session_id
  attribute :views, :default => 0
  attribute :created_at, :default => lambda { Time.zone.now }

  # iterate through attr keys and set instance vars
  def initialize(attr = {})
    @errors = ActiveModel::Errors.new(self)
    unless attr.nil?
      attr.each do |name, value|
        setter = "#{name}="
        next unless respond_to?(setter)
        send(setter, value)
      end
    end
  end

  def addOrUpdate(key, value)
    self[key] = value
  end

  def save
    return false unless valid?
    run_callbacks :save do
      Couch.client.set(self.session_id, self)
    end
    true
  end

  def self.find(key)
    return nil unless key
    begin
      doc = Couch.client.get(key)
      self.new(doc)
    rescue Couchbase::Error::NotFound => e
      nil
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails model nosql dynamic-data couchbase


    【解决方案1】:

    您为什么不喜欢使用来自 couchbase-model gem 的查找、保存和创建方法?

    class Couchbase::Error::RecordInvalid < Couchbase::Error::Base
      attr_reader :record
    
      def initialize(record)
        @record = record
        errors = @record.errors.full_messages.join(", ")
        super("Record Invalid: #{errors}")
      end
    end
    
    class SomeRequest < Couchbase::Model
      include ActiveModel::Validations
    
      attribute :session_id
      attribute :views, :default => 0
      attribute :created_at, :default => lambda { Time.zone.now }
    
      validates_presence_of :session_id
    
      before_save do |doc|
        if doc.valid?
          doc
        else
          raise Couchbase::Error::RecordInvalid.new(doc)
        end
      end
    
      def initialize(*args)
        @errors = ActiveModel::Errors.new(self)
        super
      end
    
    end
    

    你可能是对的,默认情况下添加验证钩子是值得的,我想我会在下一个版本中这样做。上面的示例适用于版本 0.3.0

    考虑到updateOrAdd我建议你只使用方法#save它会检查密钥是否被持久化(目前通过检查id属性),如果记录还没有密钥,它将生成密钥并更新它。

    更新

    0.4.0 版本中,我在 gem 中添加了验证钩子,因此上面的示例可以更简单地重写。

    class SomeRequest < Couchbase::Model
      attribute :session_id
      attribute :views, :default => 0
      attribute :created_at, :default => lambda { Time.zone.now }
    
      validates_presence_of :session_id
    end
    

    【讨论】:

    • 谢谢!但我仍然只能访问列为“属性”的属性。这个想法是我实际上并不知道文档中有哪些属性。我找到了一个解决方案,将所有内容放在一个名为“属性”的 json 对象数组中,但这并不完美。
    • 我使用的是 0.1.0,来自官方示例。 0.4.0 更时尚,谢谢!但不能解决问题。
    • 好的。我看到了问题,你想动态定义方法吗?
    猜你喜欢
    • 1970-01-01
    • 2010-09-23
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2017-05-15
    • 2013-07-27
    • 1970-01-01
    相关资源
    最近更新 更多