2009-10-20 55 views
1

我在控制器中發現了一些獲取action_name的信息,但我需要知道它在我的模型中。我有點第二次猜測自己,並想知道這是否是你需要或可以從模型中得到的東西,但我不確定。請讓我知道是否有辦法在我的模型中獲得像action_name這樣的內容。如何從RoR模型中獲取當前動作?

+3

你可以給你想要做的更多信息的動作?您不需要從模型中訪問您的控制器。也許我們可以幫助提出一個更清潔的方法。 – 2009-10-20 19:55:42

回答

2

從嚴格意義上說,您的模型不應該對訪問它的控制器有任何可見性,即這是不好的做法。

在任何情況下,如果您仍想訪問它,您可以將控制器的對象'控制器'傳遞給您的模型方法名稱。它包含您需要的所有信息。

 
controller.action_name 

會給你動作名稱。

+0

我同意,這是非常糟糕的做法。 – ohdeargod 2009-10-20 20:35:15

0

我不確切地知道你在做什麼,但我有感覺的例子,就像我需要從模型到達控制器一樣。當然不好的做法。

另一方面,有時候控制器有數據(例如當前用戶),模型可能需要 - 比如說發送一個郵件,說明一個項目已被編輯。在這種情況下,您可能需要通過電子郵件發送該項目的創建者 - 但僅限於該用戶不是當前用戶。如果我是一個編輯人員,不需要發郵件給我自己,對吧?

我用過的解決方案是使用可以訪問控制器的清掃器。

class BugSweeper < ActionController::Caching::Sweeper 
    observe Bug 

    def after_create(record) 
     email_created(record) 
    end 

    def before_update(record) 
     email_edited(record) 
    end 

    def email_created(record, user = controller.session[:user_id]) 
     editor = find_user(user) 
     if record.is_assigned? 
      TaskMailer.deliver_assigned(record, editor) unless record.editor_is_assignee?(editor) 
     end 
    end 
end 

YMMV。

0

正如別人指出這是非常糟糕的做法。你永遠不需要知道你的模型正在使用什麼動作。取決於動作的代碼通常非常脆弱。它還通過將代碼放入屬於您的控制器的模型中,模糊了Model View和Controller之間的界限。

但是,如果你在促成這件事情死心塌地,這裏有一個模型使用控制器動作的幾個選項:

  1. 使通用的方法和它們在控制器的輸出行爲。 (標準處理方式
  2. 在您的模型中製作只能在特定控制器控制器中使用的方法。 (不是很乾DRY
  3. 將操作作爲參數傳遞給方法。
  4. 使用attr_accessible生成的方法設置操作。

無論如何,下面是我的每個解決方案的示例。

通用方法例如

class MyModel < ActiveRecord::Base 
    ... 
    def do_stuff 
    # things. 
    end 

    def suitable_for_use_in_action? 
    # returns true if the model meets criteria for action 
    end 
end 

class MyModelsController < ApplicationController 

    ... 

    def index 
    @myModel = MyModel.find(params[:id]) 
    @myModel.do_stuff if @myModel.suitable_for_use_in_action? 
    end 
end 

具體動作示例

class MyModel < ActiveRecord::Base 
    ... 
    def do_stuff_in_index 
    # things that should only be called if the action is index. 
    end 
end 

class MyModelsController < ApplicationController 

    ... 

    def index 
    @myModel = MyModel.find(params[:id]) 
    @myModel.do_stuff_in_index 
    end 
end 

傳遞的動作作爲一個參數的例子。

class MyModel < ActiveRecord::Base 
    ... 
    def do_stuff(action) 
    if action == :index 
     # things that should only be called if the action is index. 
    else 
     #things to be done when called from all other actions 
    end 
    end 
end 

class MyModelsController < ApplicationController 

    ... 

    def index 
    @myModel = MyModel.find(params[:id]) 
    @myModel.do_stuff(:index) 
    end 
end 

設置與attr_accessible例如

class MyModel < ActiveRecord::Base 
    ... 
    attr_accessible :action 

    def do_stuff 
    if @action == :index 
     # things that should only be called if the action is index. 
    else 
     #things to be done when called from all other actions, or when called while @action is not set. 
    end 
    end 
end 

class MyModelsController < ApplicationController 

    ... 

    def index 
    @myModel = MyModel.find(params[:id]) 
    @myModel.action = :index 
    @myModel.do_stuff 
    end 
end