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
我是红宝石的新手,而且它是轨道所以,希望你们不会低估我的问题,因为我谷歌周围但不能理解差异。
答案 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等于令牌的记录之前。
我相信unscoped
是deprecated。
答案 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