0

我想充分利用 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
4

1 回答 1

0

你为什么不喜欢使用来自 couchbase-model gem 的 find、save 和 create 方法?

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
于 2012-09-25T20:49:30.987 回答