gpt4 book ai didi

ruby-on-rails - 为什么要使用 ActiveSupport::Concern 而不仅仅是一个普通的模块?

转载 作者:行者123 更新时间:2023-12-04 01:50:15 27 4
gpt4 key购买 nike

我从来不明白为什么必须使用 ActiveSupport::Concern 用于 mixins 而不是普通模块。对于 ActiveSupport::Concern 提供的内容(至少在 Rails 5 中)是否有一个简单的答案,即不使用 ActiveSupport::Concern 的简单模块会做什么?

最佳答案

来自 https://api.rubyonrails.org/classes/ActiveSupport/Concern.html :

一个典型的模块如下所示:

module M
def self.included(base)
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end

module ClassMethods
...
end
end

通过使用 ActiveSupport::Concern上面的模块可以写成:
require 'active_support/concern'

module M
extend ActiveSupport::Concern

included do
scope :disabled, -> { where(disabled: true) }
end

class_methods do
...
end
end

此外,它优雅地处理模块依赖关系。给定一个 Foo模块和 Bar依赖于前者的模块,我们通常会编写以下内容:
module Foo
def self.included(base)
base.class_eval do
def self.method_injected_by_foo
...
end
end
end
end

module Bar
def self.included(base)
base.method_injected_by_foo
end
end

class Host
include Foo # We need to include this dependency for Bar
include Bar # Bar is the module that Host really needs
end

但是为什么要 Host关心 Bar的依赖,即 Foo ?我们可以尝试将这些隐藏在 Host 中。直接包括 FooBar :
module Bar
include Foo
def self.included(base)
base.method_injected_by_foo
end
end

class Host
include Bar
end

不幸的是,这不起作用,因为 Foo包括在内,它的基础是 Bar模块,而不是 Host类(class)。与 ActiveSupport::Concern ,模块依赖关系得到正确解决:
require 'active_support/concern'

module Foo
extend ActiveSupport::Concern
included do
def self.method_injected_by_foo
...
end
end
end

module Bar
extend ActiveSupport::Concern
include Foo

included do
self.method_injected_by_foo
end
end

class Host
include Bar # It works, now Bar takes care of its dependencies
end

关于ruby-on-rails - 为什么要使用 ActiveSupport::Concern 而不仅仅是一个普通的模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53488519/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com