【问题标题】:Simple boolean data update with mongdb?使用 mongodb 进行简单的布尔数据更新?
【发布时间】:2011-01-16 05:17:45
【问题描述】:

我正在使用 Rails 和 mongoid 来处理 mongodb。

通常在使用 Active:Record 时在 rails 中,您可以访问方法 .toggle!这只是允许您反转数据库中布尔字段的值。

很遗憾,这个方法不适用于 mongoDB:

user = User.first
user.toggle!(:admin)
NoMethodError: undefined method `toggle!' for #<User:0x00000100eee700>

这很不幸...而且很愚蠢,如果没有一些复杂的代码,我不知道如何解决...

关于如何简洁地达到相同结果的任何建议?

谢谢,

亚历克斯

ps:还有一个问题是,当我想修改该字段时,它会再次通过验证...并且它要求我没有保存在数据库中的 :password ,所以:

User.first.admin = !User.first.admin

甚至不会工作:(

【问题讨论】:

    标签: ruby-on-rails mongodb boolean toggle mongoid


    【解决方案1】:

    这里的问题特别是 mongoid,而不是 mongodb。 toggle!ActiveRecord::Base 的一部分,但幸运的是它并不难复制。

    def toggle!(field)
      send "#{field}=", !self.send("#{field}?")
      save :validation => false
    end
    

    将其添加到您的模型中(或将其添加到模块中,然后将其包含在您的模型中),您的 Mongoid 模型将获得与您在 AR 中习惯的功能相同的功能。它将读取字段的值,反转它,写入它(通过 setter,根据toggle! 文档),然后保存文档,绕过验证。

    【讨论】:

    • 这真是太棒了!正是我要找的... :) 我不知道 send 的语法吗?我不确定它到底是做什么的?
    • send 调用一个方法来(“发送消息”)一个对象。 @foo.bar(:baz)@foo.send("bar", :baz) 相同 - 因为您使用 send 指定方法名称,所以您可以传递变量等。这在 Ruby 元编程中被大量使用。
    • 感谢您的解释。但是,经过彻底测试后,它实际上并没有绕过所有验证。我有一个 validates_length_of :password, :minimum => 6, :maximum => 40,并且使用切换将通过我的密码长度错误... :( 但不是在验证存在等。它跳过attr_accesible 等,所以除了长度验证之外几乎是完美的
    【解决方案2】:
    # Get object's boolean field and toggle it
    # @param [Object] mongoid object 
    # @param [String, Symbol] flag
    # @example 
    #  foo = User.find('123')
    #  toggle_flag!(object: foo, flag: :bar)
    
    def toggle_flag!(object:, flag:)
      object.update(flag => !object[flag])
      object.save!
    end
    

    【讨论】:

    • 完成!我用 YARD 来解释。
    【解决方案3】:

    好的,由于类型原因,验证无效,代码应该是:

    save :validate => false  (not :validation)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-11
      • 1970-01-01
      • 2019-04-24
      • 2015-12-03
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多