2009-07-08 85 views
2

我正在編寫我的第一個rails插件,可以使用一些幫助。以一種非常簡單的方式,我希望允許開發人員指定一個可以通過rake任務計算的值。我在想這樣的事情...爲Rails編寫ActiveRecord插件

class User < ActiveRecord::Base 
    monitor "Users", count 
    monitor "Active Users", count("activated_at != NULL") 
end 
  1. 我猜顯示器需要使用的ActiveRecord :: Base的一個類的方法,但如何/我在哪裏,我的插件指定了嗎?
  2. monitor函數的參數不應該是值而是要執行的代碼塊。我不太清楚指定這個的最好方法,並保持簡單的語法。也許它必須是monitor "Active Users", {count "activated_at != NULL"}
  3. 如果開發者不需要指定User.count,只需要count,即它會自動拾取類(並且塊將在類上調用而不是實例)。如果這是不可能的,我想沒有理由將監控語句放入模型中(見#5)。
  4. 這些值的實際計數(即塊的執行)將由rake任務離線完成。 monitor函數應該如何使這些塊可用於rake任務?將它們存儲在類變量中?
  5. 也許監視語句根本不需要在模型中指定。也許它會讓它混亂,所以我會歡迎任何其他地方放置它們。

我只是在草擬出我的想法,並試圖弄清楚在Ruby中什麼是不可能的。任何幫助讚賞。

更新:我會盡量在插件的目的上更加清晰。我希望開發人員能夠定義應該由rake任務監視的度量。 rake任務將遍歷這些度量標準,並將這些值寫入文件(我簡化了一下)。耙任務將是非常簡單的,像rake monitors:update(即不需要PARAMS)

回答

0

感謝您的所有幫助,但是我採用了不同的方法(摘錄如下)。

我沒有在模型中指定屬性,而是使用了每當gem時看到的方法。我放在一個ruby文件 「dashboard.rb」 在我的config目錄:

dashboard "Users", User.count 
dashboard "Activated Users", User.count('activated_at') 

我的lib中包含兩個功能:

def self.dashboard(name, attribute) 
     puts "** dailydashboard: #{name} = #{attribute.to_s}" 
    end 

    def self.update(file) 
    eval File.read(file) 
    end 

基本上,我的耙子任務調用update,它加載dashboard.rbeval uates它並多次調用dashboard功能,它輸出這樣的:

** dailydashboard: Users = 2 
** dailydashboard: Activated Users = 1 

對不起,房前屋後去人有點點。對於背景/離線的東西,這看起來像一個非常簡單的方法,並做我所需要的。儘管感謝您的幫助!

0

嘗試看代碼爲named_scope

最新設計的耙任務看起來像?

rake monitor:user:active_users?

OT:

activated_at is not null是要

試想想,爲什麼不能忘記定義顯示器的SQL,而只使用named_scopes?在那裏你不會返回select *,你可以做select count(*)

+0

謝謝,你是對的SQL - 這只是一個例子。我認爲named_scopes將會非常有用,但它並不能完全解決我的問題。我更新了這個問題,提供了更多關於插件試圖實現的信息。 – ideasasylum 2009-07-08 13:04:46

1

你可能把rake任務的定義放在錯誤的地方。該模型應該只包含對其任何消費者有效的邏輯,而不關注像rake這樣的特定應用程序。

更好的方法可能是在模型中定義一些命名的作用域,並指定您希望在您的rake任務中可用的操作。指定的範圍可以在應用程序的其他區域輕鬆重用。模型可以像這樣(注意,這是一個Rails功能 - 無需進行任何部分所需的工作):

class User < ActiveRecord::Base 
    named_scope :active_users, :conditions => "activated_at != NULL" 
end 

然後您可以創建一個非常簡單的DSL,可以耙文件內使用(例如,在lib/tasks/count.rake)。東西,可以讓你做到這一點,例如:

require "your-plugin" 
namespace :count do 
    # Make your plugin rewrite this internally to User.count 
    YourPlugin::CountTask.new :users 

    # Make your plugin rewrite this to User.active_users.count 
    YourPlugin::CountTask.new :users, :active_users 

    # Perhaps allow usage of blocks as well? 
    YourPlugin::CountTask.new :users, :complicated do 
    User.count(complex_conditions) 
    end 
end 

這應該然後命名count:userscount:users:active_userscount:users:complicated任務提供給用戶。

+0

我親自指出了奧馬爾關於named_scopes的觀點。絕對有用。我已經用更多的信息更新了這個問題。我希望這次能更有意義。 – ideasasylum 2009-07-08 13:10:58

0

像這樣的東西應該做你想要什麼:

module Monitored 
    @@monitors = [] 
    def self.monitor(name, method) 
    @@monitors.push [name, method] 
    end 
    def self.run_monitor(name) 
    send @@monitors.select{|m| m[0] == name}[0][1] 
    end 
end 

未經檢驗的,但你的想法,我希望。