为什么不包含模块方法覆盖以前包含的模块方法?

时间:2017-07-24 18:21:12

标签: ruby-on-rails ruby

我想有条件地覆盖gem内部定义的方法。我的想法是有条件地包含一个模块,其中包含我希望覆盖的方法。但我发现在我希望覆盖的模块之后简单地包含一个模块,并没有像我预期的那样覆盖这些方法。请参阅以下示例:

这些是我想用以下方法覆盖gem方法的方法:

module SocializationsOverideConcern
  extend ActiveSupport::Concern

  def follow!(followable)
    Socialization::RedisStores::Follow.follow!(self, followable)
    Socialization::ActiveRecordStores::Follow.follow!(self, followable)
  end

  def unfollow!(followable)
    Socialization::RedisStores::Follow.unfollow!(self, followable)
    Socialization::ActiveRecordStores::Follow.unfollow!(self, followable)

    NotificationDismissalService.new.call(followable, user: self, dont_match_trigger: true, destroy: true)
  end

  def like!(likeable)
    Socialization::RedisStores::Like.like!(self, likeable)
    Socialization::ActiveRecordStores::Like.like!(self, likeable)
  end

  def unlike!(likeable)
    Socialization::RedisStores::Like.unlike!(self, likeable)
    Socialization::ActiveRecordStores::Like.unlike!(self, likeable)
  end
end

这是我的班级定义:

class User < ActiveRecord::Base

  acts_as_liker
  acts_as_likeable
  acts_as_follower
  acts_as_followable
  acts_as_mentionable

  include SocializationsOverideConcern if $rollout.active?(:redis_to_mysql)

方法如下!,取消关注!在社交宝石中定义了等。并通过上面的acts_as调用包含。

无论如何,这基本上就是我想要完成的事情,要覆盖以下!,取消关注!,就像!,而不像! redis_to_mysql卷展栏处于活动状态的方法。

我如何做到这一点?

1 个答案:

答案 0 :(得分:0)

如果条件在应用初始化后的某个时间点变为true,则send User条件变为true后的include方法。 e.g。

def activate_rollout
  $rollout.activate(:redis_to_msql)
  User.send(:include, SocializationsOverideConcern)
end

$rollout.active?(:redis_to_mysql) # => false

User.include? SocializationsOverideConcern # => false

activate_rollout

$rollout.active?(:redis_to_mysql) # => true

User.include? SocializationsOverideConcern # => true

另一种方法是在方法体中添加条件并使用super

module SocializationsOverideConcern
  extend ActiveSupport::Concern

  def rollout_active?
    $rollout.active?(:redis_to_mysql)
  end

  def follow!(followable)
    return super unless rollout_active?
    Socialization::RedisStores::Follow.follow!(self, followable)
    Socialization::ActiveRecordStores::Follow.follow!(self, followable)
  end

  def unfollow!(followable)
    return super unless rollout_active?
    Socialization::RedisStores::Follow.unfollow!(self, followable)
    Socialization::ActiveRecordStores::Follow.unfollow!(self, followable)

    NotificationDismissalService.new.call(followable, user: self, dont_match_trigger: true, destroy: true)
  end

  def like!(likeable)
    return super unless rollout_active?
    Socialization::RedisStores::Like.like!(self, likeable)
    Socialization::ActiveRecordStores::Like.like!(self, likeable)
  end

  def unlike!(likeable)
    return super unless rollout_active?
    Socialization::RedisStores::Like.unlike!(self, likeable)
    Socialization::ActiveRecordStores::Like.unlike!(self, likeable)
  end
end

class User < ActiveRecord::Base

  acts_as_liker
  acts_as_likeable
  acts_as_follower
  acts_as_followable
  acts_as_mentionable

  include SocializationsOverideConcern
end

这样总是包含模块,但条件移动到方法执行中。如果您需要在条件返回到false

时恢复默认功能,这可能更为可取
相关问题