如何从RoR中的模型中获取当前操作?

时间:2009-10-20 19:42:12

标签: ruby-on-rails model controller

我在控制器中找到了一些获取action_name的信息,但我需要知道模型中的内容。我是第二次猜测自己,并想知道这是否是你需要或可以从模型中得到的东西,但我不确定。如果有办法在我的模型中获得类似action_name的内容,请告诉我。

3 个答案:

答案 0 :(得分:2)

严格来说,你的模型不应该对访问它的控制器有任何可见性,即这是不好的做法。

在任何情况下,如果您仍想访问它,您可以将控制器中的对象'controller'传递给模型方法名称。它包含您需要的所有信息。

controller.action_name

也会给你动作名称。

答案 1 :(得分: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

因人而异。

答案 2 :(得分:0)

正如其他人所指出的,这是非常糟糕的做法。您永远不需要知道您的模型正在使用什么操作。依赖于操作的代码通常非常脆弱。它还模糊了模型视图和控制器之间的界限,方法是将代码放在属于控制器的模型中。

但是,如果你已经决定实现它,那么在模型中使用控制器动作还有一些选项:

  1. 制作通用方法并对控制器中的输出进行操作。 (标准的做事方式
  2. 在模型中创建仅在特定控制器控制器中使用的方法。 (不是很干
  3. 将操作作为参数传递给方法。
  4. 使用attr_accessible生成的方法设置操作。
  5. 无论如何,以下是我的每个解决方案的示例。

    通用方法示例

    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