Ruby on rails 我能用唐卡斯吗!而不是在一个前保存钩子中的downcase来更改一个值?

Ruby on rails 我能用唐卡斯吗!而不是在一个前保存钩子中的downcase来更改一个值?,ruby-on-rails,ruby,string,hook,before-save,Ruby On Rails,Ruby,String,Hook,Before Save,我对Ruby是新手。我正在学习Michael Hartl的Ruby on Rails教程,以下代码用于用户模型: before_save { self.email = email.downcase } 在这种情况下,是否可以改为写: before_save { self.email.downcase! } 或者这种方法是因为某种原因而存在缺陷?如果是,你能给我一个快速解释为什么吗?使用downcase在此处修改属性是完全可以接受的,只要您能够保证设置了电子邮件。如果email为nil,如果您

我对Ruby是新手。我正在学习Michael Hartl的Ruby on Rails教程,以下代码用于用户模型:

before_save { self.email = email.downcase }
在这种情况下,是否可以改为写:

before_save { self.email.downcase! }

或者这种方法是因为某种原因而存在缺陷?如果是,你能给我一个快速解释为什么吗?

使用
downcase
在此处修改属性是完全可以接受的,只要您能够保证设置了
电子邮件
。如果
email
nil
,如果您尝试调用
downcase,您将遇到
NoMethodError
在上面。这也适用于您的第一个示例

另外,实际上不需要指定
self
来访问模型上的属性。以下几点就足够了。(添加检查是否存在电子邮件。)


使用
downcase
在此处修改属性是完全可以接受的,只要您能够保证设置了
电子邮件
。如果
email
nil
,如果您尝试调用
downcase,您将遇到
NoMethodError
在上面。这也适用于您的第一个示例

另外,实际上不需要指定
self
来访问模型上的属性。以下几点就足够了。(添加检查是否存在电子邮件。)

TL;博士 在这种情况下,是否可以改为书写

before_save { self.email.downcase! }
或者这种方法是因为某种原因而存在缺陷

不要这样做,除非bang方法位于方法链的末尾,或者除非您确信自己不关心返回值。坏事™ 否则可能会发生

相反,您应该使用一些处理拐角情况的工具,如以下之一:

  • 在保存{self.email.downcase!之前,除非self.email.blank?}
  • 保存之前{self.email=self.email.to_.downcase}
解释 像bang这样的一些方法的问题是,它们不提供您认为它们提供的返回值。而
self.email.downcase
将对self的email属性进行降级,返回值可能为零。例如:

"A".downcase!
#=> "a"

"".downcase!
#=> nil

"z".downcase!
#=> nil
nil.downcase
# NoMethodError: undefined method `downcase' for nil:NilClass
更糟糕的是,如果电子邮件为零,则无论您使用的是
downcase
还是
downcase,都会引发异常。例如:

"A".downcase!
#=> "a"

"".downcase!
#=> nil

"z".downcase!
#=> nil
nil.downcase
# NoMethodError: undefined method `downcase' for nil:NilClass
为了简单地确保email属性是小写的,那么您可以在狭窄的情况下避免这种情况,在这种情况下,或其他因素确保email不是nil,并且您没有使用方法或钩子的返回值。但更广泛地说,火车失事的原因如下:

before_save { self.email.downcase!.gsub(?@, ' AT ') }
可能会在运行时以令人惊讶且难以调试的方式爆炸

总而言之,您当前的示例在功能上是等效的,但处理返回值的方式却完全不同。因此,您的里程数可能会有所不同。

TL;博士 在这种情况下,是否可以改为书写

before_save { self.email.downcase! }
或者这种方法是因为某种原因而存在缺陷

不要这样做,除非bang方法位于方法链的末尾,或者除非您确信自己不关心返回值。坏事™ 否则可能会发生

相反,您应该使用一些处理拐角情况的工具,如以下之一:

  • 在保存{self.email.downcase!之前,除非self.email.blank?}
  • 保存之前{self.email=self.email.to_.downcase}
解释 像bang这样的一些方法的问题是,它们不提供您认为它们提供的返回值。而
self.email.downcase
将对self的email属性进行降级,返回值可能为零。例如:

"A".downcase!
#=> "a"

"".downcase!
#=> nil

"z".downcase!
#=> nil
nil.downcase
# NoMethodError: undefined method `downcase' for nil:NilClass
更糟糕的是,如果电子邮件为零,则无论您使用的是
downcase
还是
downcase,都会引发异常。例如:

"A".downcase!
#=> "a"

"".downcase!
#=> nil

"z".downcase!
#=> nil
nil.downcase
# NoMethodError: undefined method `downcase' for nil:NilClass
为了简单地确保email属性是小写的,那么您可以在狭窄的情况下避免这种情况,在这种情况下,或其他因素确保email不是nil,并且您没有使用方法或钩子的返回值。但更广泛地说,火车失事的原因如下:

before_save { self.email.downcase!.gsub(?@, ' AT ') }
可能会在运行时以令人惊讶且难以调试的方式爆炸


总而言之,您当前的示例在功能上是等效的,但处理返回值的方式却完全不同。因此,您的里程数可能会有所不同。

原始方法调用属性设置器方法
email=
,因此是一种方法:

self.email= email.downcase
ActiveRecord然后可以做其他事情。例如,它可以跟踪更改的属性以优化数据库更新


当你用
downcase更改它时,首先调用getter,ActiveRecord返回字符串,然后在适当的位置更改字符串,ActiveRecord没有直接意识到这一点。在本例中,它可能起作用,但不养成这种习惯更安全。

原始方法调用属性设置器方法
email=
,因此是一种方法:

self.email= email.downcase
ActiveRecord然后可以做其他事情。例如,它可以跟踪更改的属性以优化数据库更新


当你用
downcase更改它时,首先调用getter,ActiveRecord返回字符串,然后在适当的位置更改字符串,ActiveRecord没有直接意识到这一点。在本例中,它可能起作用,但不养成这种习惯更安全。

欢迎使用堆栈溢出!在我看来,这是一个写得很好的问题,但我已经做了一些小的修改来清理它。您可以签出和。欢迎使用堆栈溢出!在我看来,这是一个写得很好的问题,但我已经做了一些小的修改来清理它。你可以退房。嘿,CodeGnome,谢谢你的回复。谢谢你这么仔细,我很感激你的解释。我还不熟悉rails和ruby,所以我是s