2017-07-24 107 views
0

我想有條件地覆蓋在寶石內定義的方法。我的想法是有條件地包含一個模塊和我希望覆蓋的方法。但是我發現,在我希望重寫的模塊之後簡單包含一個模塊並不像我期望的那樣覆蓋方法。請看下面的例子:爲什麼不包含之前包含的模塊方法的包含模塊方法?

這些都是我想重寫寶石方法的方法:

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調用包含。

無論如何,這基本上是我正在努力完成的,重寫follow!,unfollow !,就像!,而不像!方法,如果redis_to_mysql轉出活動。

我該如何做到這一點?

+0

有兩個問題:1)你確定'$ rollout.active?(:redis_to_mysql)'是真的嗎? 2)當它真的很好,你調用'User.ancestors'時,它輸出了什麼? –

+0

'如果$ rollout.active?(:redis_to_mysql)'實際上是無效的語法'include SocializationsOverideConcern'。我添加它只是爲了表明意圖。 – matthewalexander

+0

當我檢查User.ancestors時,我想重寫的模塊顯示在我希望覆蓋它們的模塊後面。不知道這是爲什麼...... – matthewalexander

回答

0

如果條件在應用程序初始化後的某個時間點變爲真,則條件成立後sendUserinclude方法。例如

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