使用Ruby on Rails模块的建议

时间:2011-02-08 10:41:47

标签: ruby-on-rails ruby ruby-on-rails-3 module implementation

我正在使用Ruby on Rails 3,我知道在哪种情况下使用模块会很好。

我有一个控制器,包括我以这种方式使用的很多私有方法:

class UsersController < ApplicationController

  def update
    params[:option1] = get_user_option1
    params[:option2] = get_user_option2


    if params[:option2]
      params[:saving_success] = update_user
    end

    ...

    if params[:saving_success] 
      flash[:notice] = another_method_1
    else
      flash[:error] = another_method_2
    end
  end


    private

      def update_user
        if params[:option1] == something
          @user.save
        end
      end

      def another_method_1
        params[...] = ...
      ...
  end

正如您所看到的,在私有方法中我有像ActiveRecords和params方法这样的东西。我知道在模块中你不能直接使用那些 ActiveRecords params方法,但你可以将它们作为参数传递,如下例所示:

# In the controller file
class UsersController < ApplicationController
  include Users

  def update
    params[:option] = "true"
    @users = Users.find(1)
    Users::Validations.name (@user, params[:option])
    ...
  end
end

# In the module file
module Users
  module Validations
    def Validations.name(user, param)
      user == "Test_name" if param
      # Normally the following is not possible:
      # @user == "Test_name" if params[:option]
    end
  end
end

那么,在我的案例中你有什么建议?使用单独的模块是否合适?


次要问题(目前......):

  1. 表现怎么样?

  2. P.S。 I:不要注意示例的简单性。编写它们只是为了理解我传递ActiveRecords和params方法的困境。

    P.S。 II:如果您需要其他信息,请告诉我。

1 个答案:

答案 0 :(得分:9)

模块有两个主要目的:

  1. 命名空间
  2. 混入
  3. 模块命名空间通常用于更好地组织代码并促进更安全和一致的范围。

    但模块主要用作mixins。它的Ruby提供多重继承的方式。例如,假设您有跨类访问的方法(例如跨不同的模型/控制器等)。您不必在每个类中重复那些不一定仅适用于该类的方法,而是将这些方法抽象为模块,并将包含扩展模块适当的课程。

    这取决于模块与app目录的紧密耦合程度  存储模块的位置。存储模块中的一些模式:

    1. / lib目录,如果模块没有与app /.
    2. 特别“交互”
    3. app / models目录,但可能会导致与实际的ActiveRecord模型混淆。
    4. 37 Signals introduced a pattern将它们视为“关注点”并将其存储在app / Concer中。
    5. 但是,如果您有一个仅用于用户控制器的方法,建议您将该代码放入用户模型中,因为这就是“用户”的业务逻辑所在的位置。

      通过'ActiveRecords',我假设您的意思是模型类(例如用户)。 您可以在模块中访问模型类并对它们执行ActiveRecord操作(例如User.find(:all))。

      然而,正如你猜对了,你不能使用params,你必须将它作为参数传递给模块的方法。