How should I write:
我该如何写:
if @parent.child.grand_child.attribute.present?
do_something
without cumbersome nil checkings to avoid exception:
没有繁琐的nil检查以避免异常:
if @parent.child.present? && @parent.child.grandchild.present? && @parent.child.grandchild.attribute.present?
Thank you.
谢谢你!
9 个解决方案
#1
4
Rails has object.try(:method)
:
Rails object.try(方法):
if @parent.try(:child).try(:grand_child).try(:attribute).present?
do_something
http://api.rubyonrails.org/classes/Object.html#method-i-try
http://api.rubyonrails.org/classes/Object.html method-i-try
#2
3
You could use Object#andand.
您可以使用# andand对象。
With it your code would look like this:
有了它,你的代码会变成这样:
if @parent.andand.child.andand.grandchild.andand.attribute
#3
3
You can slightly reduce it by assigning the intermediate values to some local variable:
您可以通过将中间值分配给某个局部变量来稍微减少它:
if a = @parent.child and a = a.grandchild and a.attribute
#4
2
For fun, you could use a fold:
为了好玩,你可以使用折叠:
[:child, :grandchild, :attribute].reduce(@parent){|mem,x| mem = mem.nil? ? mem : mem.send(x) }
but using andand is probably better, or ick, which I like a lot and has methods like try
and maybe
.
但是使用andand可能更好,或者是ick,我很喜欢它,它有try和maybe这样的方法。
#5
0
If the attribute you are checking is always the same, create a method in @parent.
如果要检查的属性总是相同的,那么在@parent中创建一个方法。
def attribute_present?
@parent.child.present? && @parent.child.grandchild.present? && @parent.child.grandchild.attribute.present?
end
结束
Alternatively, create has_many :through
relationship so that @parent
can get to grandchild
so that you can use :
或者,创建has_many:通过关系,以便@parent可以到达孙子,以便您可以使用:
@parent.grandchild.try(:attribute).try(:present?)
Note: present?
is not just for nil, it also checks for blank values, ''
. You can just do @parent.grandchild.attribute
if it's just nil checking
注:现在?不仅是nil,它还检查空值。你可以做@parent.grandchild。属性,如果只是nil检查
#6
0
You coult just catch the exception:
你不能只抓住例外:
begin
do something with parent.child.grand_child.attribute
rescue NoMethodError => e
do something else
end
#7
0
I suppose you can do it using a delegate
method as a result you'll have sth like
我想你可以用委托方法来做,结果你会得到类似的东西
@parent.child_grand_child_attribute.present?
#8
0
Hi Think you can use a flag variable here with rescue option
你好,你可以在这里使用一个标志变量和营救选项
flag = @parent.child.grand_child.attribute.present? rescue false
if flag
do_something
end
#9
0
You could do this:
你可以这样做:
Optional = Struct.new(:value) do
def and_then(&block)
if value.nil?
Optional.new(nil)
else
block.call(value)
end
end
def method_missing(*args, &block)
and_then do |value|
Optional.new(value.public_send(*args, &block))
end
end
end
Your check would become:
你的检查将成为:
if Optional.new(@parent).child.grand_child.attribute.present?
do_something
Source: http://codon.com/refactoring-ruby-with-monads
来源:http://codon.com/refactoring-ruby-with-monads
#1
4
Rails has object.try(:method)
:
Rails object.try(方法):
if @parent.try(:child).try(:grand_child).try(:attribute).present?
do_something
http://api.rubyonrails.org/classes/Object.html#method-i-try
http://api.rubyonrails.org/classes/Object.html method-i-try
#2
3
You could use Object#andand.
您可以使用# andand对象。
With it your code would look like this:
有了它,你的代码会变成这样:
if @parent.andand.child.andand.grandchild.andand.attribute
#3
3
You can slightly reduce it by assigning the intermediate values to some local variable:
您可以通过将中间值分配给某个局部变量来稍微减少它:
if a = @parent.child and a = a.grandchild and a.attribute
#4
2
For fun, you could use a fold:
为了好玩,你可以使用折叠:
[:child, :grandchild, :attribute].reduce(@parent){|mem,x| mem = mem.nil? ? mem : mem.send(x) }
but using andand is probably better, or ick, which I like a lot and has methods like try
and maybe
.
但是使用andand可能更好,或者是ick,我很喜欢它,它有try和maybe这样的方法。
#5
0
If the attribute you are checking is always the same, create a method in @parent.
如果要检查的属性总是相同的,那么在@parent中创建一个方法。
def attribute_present?
@parent.child.present? && @parent.child.grandchild.present? && @parent.child.grandchild.attribute.present?
end
结束
Alternatively, create has_many :through
relationship so that @parent
can get to grandchild
so that you can use :
或者,创建has_many:通过关系,以便@parent可以到达孙子,以便您可以使用:
@parent.grandchild.try(:attribute).try(:present?)
Note: present?
is not just for nil, it also checks for blank values, ''
. You can just do @parent.grandchild.attribute
if it's just nil checking
注:现在?不仅是nil,它还检查空值。你可以做@parent.grandchild。属性,如果只是nil检查
#6
0
You coult just catch the exception:
你不能只抓住例外:
begin
do something with parent.child.grand_child.attribute
rescue NoMethodError => e
do something else
end
#7
0
I suppose you can do it using a delegate
method as a result you'll have sth like
我想你可以用委托方法来做,结果你会得到类似的东西
@parent.child_grand_child_attribute.present?
#8
0
Hi Think you can use a flag variable here with rescue option
你好,你可以在这里使用一个标志变量和营救选项
flag = @parent.child.grand_child.attribute.present? rescue false
if flag
do_something
end
#9
0
You could do this:
你可以这样做:
Optional = Struct.new(:value) do
def and_then(&block)
if value.nil?
Optional.new(nil)
else
block.call(value)
end
end
def method_missing(*args, &block)
and_then do |value|
Optional.new(value.public_send(*args, &block))
end
end
end
Your check would become:
你的检查将成为:
if Optional.new(@parent).child.grand_child.attribute.present?
do_something
Source: http://codon.com/refactoring-ruby-with-monads
来源:http://codon.com/refactoring-ruby-with-monads