Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在rails中对关联进行零检查的面向对象方法_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 在rails中对关联进行零检查的面向对象方法

Ruby on rails 在rails中对关联进行零检查的面向对象方法,ruby-on-rails,ruby,Ruby On Rails,Ruby,我已经看了桑迪·梅茨的演讲好几次了。我意识到我在rails项目中到处都在进行零检查,但我不知道如何避免零检查,以及在涉及关联时如何以面向对象的方式进行零检查 以这些关联为例: #app/models/user.rb class User < ActiveRecord::Base belongs_to :blog end #app/models/blog.rb class Blog < ActiveRecord::Base belongs_to :hash_tag has

我已经看了桑迪·梅茨的演讲好几次了。我意识到我在rails项目中到处都在进行零检查,但我不知道如何避免零检查,以及在涉及关联时如何以面向对象的方式进行零检查

以这些关联为例:

#app/models/user.rb
class User < ActiveRecord::Base
  belongs_to :blog
end

#app/models/blog.rb
class Blog < ActiveRecord::Base
  belongs_to :hash_tag
  has_one :user
end

#app/models/hash_tag.rb
class HashTag < ActiveRecord::Base
  has_one :blog
end
我想找到他的博客:

@user.blog
  => nil
它在此处返回
nil
,因为该
用户
恰好没有关联的
博客
,因此如果我对该
用户
执行类似操作,则以下代码将中断应用程序:

@user.blog.title
  => undefined method `title' for nil:NilClass
简单的解决方法是以非面向对象的方式执行,只需执行nil检查(但这是我们想要避免的,因为否则nil检查在应用程序中绝对无处不在):

通过以下关联越深入,执行零检查就越麻烦,程序也就越复杂:

@user = User.find(1)
if @user.blog && @user.blog.hash_tag #checking for nil twice
  @user.blog.hash_tag.tag_name
end
什么是避免关联零检查的面向对象方法


我知道rails’,尽管Metz似乎不推荐使用
try
方法。也许当谈到rails中的关联时:
try
是最好的选择?

我认为这可能是一种选择

我会使用:
rescue
method
注意:此方法捕获异常并相应响应;如果您需要以不同的方式响应异常,请不要使用此选项。我希望你能理解

例如:

2.1.1 :001 > var1 = nil
 => nil 
2.1.1 :002 > my_val = var1.some_method

NoMethodError: undefined method `some_method' for nil:NilClass
    from (irb):2
    from /home/shiva/.rvm/rubies/ruby-2.1.1/bin/irb:11:in `<main>'

2.1.1 :003 > my_val = var1.some_method rescue ''
 => ""
try在调用nil时返回nil,无论它是否响应该方法:

nil.try(:to_i) # => nil, rather than 0

有一个漂亮的gem
,我在这种情况下使用它。通常,您需要写:

@user.blog && @user.blog.title
and
gem实现了通用的空模式
And
使用方法
And
扩展对象,该方法返回调用它的对象,除非该对象为nil。在nil的情况下,对于使用方法\u的所有方法调用,都返回NullPatern对象以返回nil

@user.blog.andand.title
当您需要检查更多情况时,它的功能更强大:

@user.blog && @user.blog.title && @user.blog.title.capitalize
变成:

@user.blog.andand.title.andand.capitalize

有一个编程设计指南叫做

以下是如何将其应用于rails模型:

#app/models/user.rb
class User < ActiveRecord::Base
  belongs_to :blog
    delegate :title, to: :blog, prefix: true, allow_nil: true
    # then you can call user.blog_title
    delegate :tag_name, to: :blog, prefix: true, allow_nil: true
    # follow LoD
end

#app/models/blog.rb
class Blog < ActiveRecord::Base
  belongs_to :hash_tag
    delegate :tag_name, to: :hash_tag, allow_nil: true
  has_one :user
end
请阅读以下链接以获取参考:


只是一个建议:不要每次都解雇
@user.blog
,您可以将它放入一个变量中,如
@user\u blog=@user.blog
,并在需要时检查它是否存在,如:
@user\u blog.present?
我查看了
gem,发现
gem与rails中的
try
方法完全相同
try
在2010年的版本2.3.2中为rails推出。最初发布的
gem是在2008年发布的,所以我认为
是一个很好的选择,直到
try
出现并内置到rails中。太好了,你自己修复了它
@user.blog.andand.title
@user.blog && @user.blog.title && @user.blog.title.capitalize
@user.blog.andand.title.andand.capitalize
#app/models/user.rb
class User < ActiveRecord::Base
  belongs_to :blog
    delegate :title, to: :blog, prefix: true, allow_nil: true
    # then you can call user.blog_title
    delegate :tag_name, to: :blog, prefix: true, allow_nil: true
    # follow LoD
end

#app/models/blog.rb
class Blog < ActiveRecord::Base
  belongs_to :hash_tag
    delegate :tag_name, to: :hash_tag, allow_nil: true
  has_one :user
end
@user = User.find(1)
@user.blog_title # no error even if there is no associated blog
@user.tag_name # no error even if there is no associatd blog or no associated hash_tag object