我说的是我观察到的,可能不一定是 Rails 约定。
例如,当我们这样做rails g post title content:text
时,您可能记得它没有default: ''
标题(字符串)和内容(文本)。这已经是对我的暗示,没有关于此的 Rails 约定,或者具体来说,默认情况下每个属性都允许为 NULL 或 nil。
使用 NULL 的优点是您可以识别哪些记录设置了这些属性。
假设我们有一个 API 服务器。如果客户端向我们的 API 服务器创建了一个帖子,我们就知道哪些属性应该具有值。让我们这样说:
client-1 的 POST 参数:
post: {title: 'Foo bar'}
- 如果 NULL 允许,将创建一个
Post(title: 'Foo bar', content: nil)
- 如果默认:'',将创建一个
Post(title: 'Foo bar', content: '')
client-2 的 POST 参数:
post: {title: 'Foo bar', content: ''}
- 如果 NULL 允许,将创建一个
Post(title: 'Foo bar', content: '')
- 如果默认:'',将创建一个
Post(title: 'Foo bar', content: '')
从上面,请注意,如果我们有默认值:'',那么我们无法知道客户端是否真的打算有一个空content
值,因为对于客户端 1 和客户端 2,content
post 的结果值将具有 '' (空)无论如何。content
但是如果我们有 NULL 允许的属性,那么我们仍然可以通过不在参数中传递属性来识别客户端是否打算没有值。这是一个重要的用例。
根据您的项目和属性的用途,您可以使用 NULL-allowed 或为该属性设置默认的空字符串。
现在,您遇到的允许 NULL 的一个主要问题是您不能保证每个值都是 a String
,因此如果是 NULL 或 nil ,您<%= @user.profile.location.upcase %>
将引发错误。location
这可能有点烦人,特别是如果您有像您的示例这样的方法链
<%= @user.profile.location.upcase.downcase %>
如果为 nil,这将是一个问题@user.profile.location
,因为您必须优雅地确保它不会引发错误。如果@user.profile
为 nil,这也将是一个问题(假设您允许@user.profile
为 nil)。通常,您将执行以下操作来完成这项工作:
<% if !@user.profile.nil? && !@user.profile.location.nil? %>
<%= @user.profile.location.upcase.downcase %>
<% end %>
if
只要您有更长的链接方法来优雅地确保它不会引发任何错误,这种情况仍然可以持续很长时间。
使用.try()
可能会“清理”它。我经常使用它,尤其是在模板文件中。解决方案将像下面这样更干净,尽管可能会让那些不知道的人感到困惑:
<%= @user.profile.try(:location).try(:upcase).try(:downcase) %>
如果其中一个.location
或.upcase
为 nil,它将返回 nil,并且不再加注undefined method ... for NilClass
。