我想在以下两个结构之间澄清一下?

时间:2014-12-11 10:26:41

标签: ruby-on-rails ruby devise

loop do
  token = Devise.friendly_token
  break token unless User.where(authentication_token: token).first
end  

loop do
  token = Devise.friendly_token
  break token unless self.class.unscoped.where(authentication_token: token).first
end  

我是红宝石的新手,而且它是轨道所以,希望你们不会低估我的问题,因为我谷歌周围但不能理解差异。

2 个答案:

答案 0 :(得分:2)

差异为User.where vs self.class.unscoped。他们基本上做同样的事情。

在第一个构造中,类名User被硬编码到表达式中。因此构造只会在User类上调用where。 User类必须响应where消息;它必须有一个名为where的类方法。

在第二个构造中,派生了类名。在Ruby中,self指的是您当前正在使用的实例。如果在实例中调用self.class,则会获得实例的类名。例如:

apple = Apple.new
puts apple.class.name
# => "Apple"

所以第二个构造可以在任何类中使用。

最后一个区别是unscoped来电。这是一个ActiveRecord方法,它删除类上任何已定义的范围。想象它"删除任何过滤器"在查找authentication_token等于令牌的记录之前。

我相信unscopeddeprecated

答案 1 :(得分:1)

鉴于您在课程用户,例如在user.rb中,self.class映射到User。所以区别实际上是另一个范围添加到where子句:

class User
  def some_method_to_find_token
    loop do
      token = Devise.friendly_token
      break token unless User.where(authentication_token: token).first
    end  
  end 

  def some_other_method_to_find_token
    loop do
      token = Devise.friendly_token
      break token unless User.unscoped.where(authentication_token: token).first
    end 
  end
end

我想如果没有令牌,我的意图是创建一个新令牌。并且可能存在可能过滤掉deleted_users的默认范围。实际上不是一个非常好的编码示例。第一个循环是不必要的,因为您始终必须检查此标记是否设置为已删除的用户。

class User
  def new_untaken_token
    loop do
      token = Devise.friendly_token
      break token unless User.unscoped.exists?(authentication_token: token)
    end  
  end 
end

这也可以通过递归方式编写:

class User
  def new_untaken_token
    token = Devise.friendly_token                         # Create a new token
    if User.unscoped.exists?(authentication_token: token) # check if it exists
      new_untaken_token                                   # find another one
    else
      token                                               # use token
    end
  end 
end