【问题标题】:How to setup default attributes in a ruby model如何在 ruby​​ 模型中设置默认属性
【发布时间】:2010-05-22 21:35:52
【问题描述】:

我有一个模型 User,当我创建一个模型时,我想实用地设置一些 API 密钥,具体来说:
@user.apikey = Digest::MD5.hexdigest(BCrypt::Password.create("jibberish").to_s)

我希望能够运行 User.create!(:email=>"something@test.com") 并让它创建一个具有随机生成的 API 密钥和秘密的用户。

我目前正在控制器中执行此操作,但是当我尝试将默认用户添加到 seeds.rb 文件时,我收到 SQL 错误(说我的 apikey 为空)。

我尝试覆盖 save 定义,但是当我更新模型时这似乎会导致问题,因为它会覆盖值。我尝试覆盖 initialize 定义,但这会返回 nil:NilClass 并破坏事物。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: ruby-on-rails ruby rails-models


    【解决方案1】:

    使用回调和 ||= ( = 除非对象不是 nil ) :)

    class User < ActiveRecord::Base
      before_create :add_apikey #or before_save
    
      private
      def add_apikey
        self.apikey ||= Digest::MD5.hexdigest(BCrypt::Password.create(self.password).to_s)
      end
    end
    

    但你绝对应该看看deviseauthlogicclearance gems

    【讨论】:

    • 我认为 before_create 可能很好,但如果他正在验证 apikey 的存在,他需要在 before_validation 中进行验证。
    • 如果我执行User.new(params) 那么@user.save 是否运行before_create 过滤器?
    • 是的,因为在这种情况下保存实际上是作为创建,因为@user.new_record? 将返回 true。
    • 谢谢!我最终选择了这个解决方案,它似乎相当优雅并且效果很好!谢谢!
    • @webdestroya:如果两个用户的密码相同怎么办?
    【解决方案2】:

    如果在您的save 定义中检查apikey 是否为nil,如果是,您设置它怎么办?

    【讨论】:

    • 运行create! 时是否调用了save def? (对不起,红宝石菜鸟)
    【解决方案3】:

    看看ActiveRecord::Callbacks,尤其是before_validation

    【讨论】:

    • 我想要做的是能够将电子邮件传递给一个新的用户对象,然后创建它。我希望模型本身生成一个 APIkey 和一个 Secret,这样每当我创建一个用户时,我就知道 API 密钥会在那里。
    • 我明白这一点。我对 Tadas 回复的评论是,如果您不接受没有 apikey 的用户,则需要在 before_validation 之前进行,而不是 before_create,因为 before_create 发生在验证之后。
    【解决方案4】:
    class User
        def self.create_user_with_digest(:options = { })
            self.create(:options)
            self.apikey = Digest::MD5.hexdigest(BCrypt::Password.create("jibberish").to_s)
            self.save
            return self
        end
    end
    

    然后你可以调用 User.create_user_with_digest(:name => "bob") 并且你会得到一个自动创建并分配给用户的摘要,你可能想要生成 api 密钥除了 MD5 之外的另一个库,例如 SHA256,您还应该放置一些用户可输入的字段、不断增加的数字(例如当前日期时间)和盐。

    希望对你有帮助

    【讨论】:

      【解决方案5】:

      我相信这行得通...只需将方法放入您的model

      def apikey=(value)  
        self[:apikey] = Digest::MD5.hexdigest(BCrypt::Password.create("jibberish").to_s)  
      end
      

      【讨论】:

      • 我仍然需要能够从存储 APIkey 的数据库中填充用户...当我基本上尝试为函数分配值时,此解决方案会出现问题吗?跨度>
      猜你喜欢
      • 2013-09-15
      • 2014-08-17
      • 2017-05-02
      • 2017-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多