我觉得这不适合做装饰。在rails中,decorators主要用视图中使用的表示逻辑包装模型对象。它们作为单个对象的扩展,允许您在逻辑上分离对象的不同任务。
例如:
class User
def born_on
Date.new(1989, 9, 10)
end
end
class UserDecorator < SimpleDelegator
def birth_year
born_on.year
end
end
当涉及到多个对象交互的类似过程的操作时,decorator不是一个很合适的方法。
相反,您应该看到的是服务对象模式,在该模式中,您可以创建执行单个任务的单用途对象:
class SubscriptionService
attr_accessor :user, :list
def initialize(user, list)
@user = user
@list = list
end
def self.perform(user, list)
self.new(user, list).perform
end
def perform
@subscription = Subscription.new(user: @user, list: @list)
log_subscription_attempted
if @subscription.create
send_welcome_email
# ...
else
log_failure_reason
# ...
end
@subscription
end
private
def send_welcome_email
# ...
end
def log_subscription_attempted
# ...
end
def log_failure_reason
# ...
end
end
但是你也应该考虑你的模型是否正确。在本例中,您希望三个模型相互连接:
class User
has_many :subscriptions
has_many :subscription_lists, through: :subscriptions
end
class Subscription
belongs_to :user
belongs_to :subscription_list
validates_uniqueness_of :user_id, scope: :subscription_list_id
end
# or topic
class SubscriptionList
has_many :subscriptions
has_many :users, through: :subscriptions
end
每个模型都应该处理应用程序中的一个单独的实体/资源。所以
SubscriptionList
例如,模型不应该直接参与订阅单个用户。如果您的模型越来越胖,这可能是一个迹象,表明您将太多内容塞进了一组太小的业务逻辑对象中,或者表明数据库设计设置得很差。