2017-06-12 79 views
3

我正在使用應用程序記錄來簡化整個應用程序中的共享邏輯。在Rails 5應用程序記錄類中包含模塊

下面是一個爲布爾及其反轉寫入作用域的示例。這種運作良好:

class ApplicationRecord < ActiveRecord::Base 
    self.abstract_class = true 

    def self.boolean_scope(attr, opposite = nil) 
    scope(attr, -> { where("#{attr}": true) }) 
    scope(opposite, -> { where("#{attr}": false) }) if opposite.present? 
    end 
end 

class User < ApplicationRecord 
    boolean_scope :verified, :unverified 
end 

class Message < ApplicationRecord 
    boolean_scope :sent, :pending 
end 

我的應用程序記錄類有足夠長的時間這是有意義對我來說,它分解成單獨的模塊,並根據需要加載這些。

這是我嘗試的解決方案:

class ApplicationRecord < ActiveRecord::Base 
    self.abstract_class = true 
    include ScopeHelpers 
end 

module ScopeHelpers 
    def self.boolean_scope(attr, opposite = nil) 
    scope(attr, -> { where("#{attr}": true) }) 
    scope(opposite, -> { where("#{attr}": false) }) if opposite.present? 
    end 
end 

class User < ApplicationRecord 
    boolean_scope :verified, :unverified 
end 

class Message < ApplicationRecord 
    boolean_scope :sent, :pending 
end 

在這種情況下,我沒有得到一個加載錯誤,但boolean_scope然後在UserMessage不確定。

有沒有一種方法可以確保包含的模塊在適當的時候被加載,並且可用於應用程序記錄及其繼承模型?


我也試圖讓模型直接包含模塊,但沒有解決問題。

module ScopeHelpers 
    def self.boolean_scope(attr, opposite = nil) 
    scope(attr, -> { where("#{attr}": true) }) 
    scope(opposite, -> { where("#{attr}": false) }) if opposite.present? 
    end 
end 

class User < ApplicationRecord 
    include ScopeHelpers 
    boolean_scope :verified, :unverified 
end 

class Message < ApplicationRecord 
    include ScopeHelpers 
    boolean_scope :sent, :pending 
end 

回答

4

作爲替代@帕文的答案,你可以這樣做:

module ScopeHelpers 
    extend ActiveSupport::Concern # to handle ClassMethods submodule 

    module ClassMethods 
    def boolean_scope(attr, opposite = nil) 
     scope(attr, -> { where(attr => true) }) 
     scope(opposite, -> { where(attr => false) }) if opposite.present? 
    end 
    end 
end 

# then use it as usual 
class ApplicationRecord < ActiveRecord::Base 
    include ScopeHelpers 
    ... 
end 
1

UserMessage類似乎並沒有被繼承ApplicationRecord。他們將如何訪問::boolean_scope

試試這個:

class User < ApplicationRecord 
    boolean_scope :verified, :unverified 
end 

class Message < ApplicationRecord 
    boolean_scope :sent, :pending 
end 
+0

良好的漁獲物。不幸的是,這些模型繼承了應用程序記錄。 AFAIK這個問題似乎與繼承無關,因爲我也嘗試過直接包含模塊。這並沒有奏效。我已經更新了這個問題。 – seancdavis

3

在這種情況下,我沒有得到一個加載錯誤,但boolean_scope然後 未定義的用戶和消息

的問題是include加方法在類的實例上。您需要使用extend

class ApplicationRecord < ActiveRecord::Base 
    self.abstract_class = true 
    extend ScopeHelpers 
end 

現在你可以這樣調用它User.boolean_scope。下面是例如,對於包括VS延長

module Foo 
    def foo 
    puts 'heyyyyoooo!' 
    end 
end 

class Bar 
    include Foo 
end 

Bar.new.foo # heyyyyoooo! 
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class 

class Baz 
    extend Foo 
end 

Baz.foo # heyyyyoooo! 
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708> 
相關問題