假设您有一个定义范围的模型,其条件也在实例方法中使用:
class Thing < ActiveRecord::Base
scope :complete?, -> {
where(
foo: true,
bar: true,
baz: true
)
}
def complete?
foo? && bar? && baz?
end
end
如果您需要更改complete?
的定义,则必须记住更改范围和实例方法。有没有一种很好的方法来合并这两个定义并使代码更干一些?
如果其中一个条件本身就是一个实例方法,则问题会稍微复杂一些:
class Thing < ActiveRecord::Base
scope :complete?, -> {
where(
foo: true,
bar: true,
# can't use instance method `base?` here for `baz` condition
# you would have to duplicate the logic:
name: 'baz'
)
}
def baz?
name == 'baz'
end
def complete?
foo? && bar? && baz?
end
end
答案 0 :(得分:3)
DRY的意思是“不要重复自己”。在那些片段中,我没有看到任何重复。所以没有什么可以干的。
你可能的意思是
有一条信息可以从中生成两种方法。如果此信息发生变化,如何才能更改一次,以免我不小心忘记更新其他地方?
嗯,你可以做一些这样的元编程体操:
class Thing < ActiveRecord::Base
FIELDS_FOR_COMPLETE = {
foo: true,
bar: true,
baz: true,
}
scope :complete?, -> {
where(FIELDS_FOR_COMPLETE)
}
def complete?
FIELDS_FOR_COMPLETE.all? do |method_name, expected_value|
self.public_send(method_name) == expected_value
end
end
end
由您来决定哪一个更容易阅读,理解和维护。
我,我选择了第一个(有些重复的)版本。这让我思考得更少。对于可能加入该项目的任何其他rails程序员来说,它也是显而易见的。