【问题标题】:Common method in model and helper模型和助手中的常用方法
【发布时间】:2011-07-31 03:12:28
【问题描述】:

我的模型中存在一个通用方法,因为它由我的模型调用。回想起来,我的观点也需要这种模式方法。为了做到这一点,我有:

  1. 将模型方法移至application_helper.rb文件
  2. 我的模型通过在我的 ActiveRecord 模型顶部添加 include ApplicationHelper 来调用 application_helper 方法

功能方面,它有效。但这是一种好的做法吗?

我的模型如下所示:

class Client < ActiveRecord::Base
  include ApplicationHelper
end

【问题讨论】:

  • 不,这是一个非常糟糕的做法。助手应该是 view 助手,如果您需要模型中的助手提供的东西,它可能会与您的视图混合。
  • 谢谢!你让我意识到我需要在我的视图中调用 Client#my_method...我一直盯着这段代码太久了...
  • 你的函数有什么依赖关系?例如它使用request 还是params

标签: ruby-on-rails design-patterns


【解决方案1】:

include ApplicationHelper 写入您的模型是不好的做法,因为 ApplicationHelper 是在视图中放置大量您需要的辅助函数的好地方。这些函数最终将作为模型的实例方法导入。这些函数大多与您的模型无关,如果它们依赖于 paramsrequest 之类的东西,它们将不起作用。以下是另外两个选项:

选项 1:

您可以在Client 类中定义方法,然后从视图中调用它,如下所示:

class Client < ActiveRecord::Base
    def self.my_class_method
    end
    def my_instance_method
    end
end

然后在你看来:

<%= Client.my_class_method %>
<%= @client.my_instance_method %>

选项 2:

lib 中创建一个单独的模块,并将其包含在您需要的地方。文件名应与模块名匹配,以便自动加载工作。

lib/my_module.rb:

module MyModule
    def my_method
    end
end

在您的模型中:

class Client < ActiveRecord::Base
    include MyModule
    def other_method
      my_method
    end
end

在 ApplicationHelper 中包含该模块,以便您的所有视图都可以使用它:

module ApplicationHelper
    include MyModule
end

那么在你看来你可以轻松调用它:

<%= my_method %>

【讨论】:

  • 选项 1 是我最终做的...我不知道为什么我试图使事情过于复杂...
  • @Coderama,我认为选项 2 更像是 Rails 方式。
  • @Coderama,对我来说,'my_method' 似乎是帮助器和模型的常见功能,将其视为一个独立的方法,它将根据接收到的参数生成一些输出。所以从逻辑上讲,它不属于 AR 模型或助手,只有他们正在使用该功能。所以最好把它放在一个单独的文件中。因此,如果另一个用户想要它,可以在不加载 AR 方法的情况下加载它。我想我正确地理解了你的问题......:D欢呼
  • 这是一种简洁的方法——Rails 5 需要的一个额外步骤是强制加载lib 目录。在application.rb中的Application类定义中添加config.autoload_paths += %W(#{config.root}/lib)
  • Rails 5 的 rails 方式是the one pointed out by Nhat Dinh
【解决方案2】:

如果您确实想将其移至帮助程序,则应将其移至 client_helper,因为它仅适用于您的客户端模型,而不适用于整个应用程序。

你说的方法,是静态类方法还是实例方法?如果它是一个实例方法,那么您的模型(即使它们在视图中)可以调用该方法。如果它是一个静态类方法,那么您的视图也可以通过像任何其他静态类方法(即Client.do_method 或其他东西)一样调用它来使用它。

我看不出它需要在帮助器中的任何理由,除非您的方法与您的模型完全无关,在这种情况下,这将是一个不同的问题。

【讨论】:

  • 我能想到很多绝对不应该出现在模型中的代码。思考:帮助确定渲染选项的代码(可以在控制器或视图中调用),检查访问权限的代码,与没有明确所有权关系的多个模型的交集工作的代码(例如,与 @ 一起工作的代码987654322@ 和 Runner 但不是 Cycler) 等等等等。
【解决方案3】:

5 模型和助手中的常用方法:

选项 1:

                    You can just define the method inside the Client class, and then call it from the view, 
                    like this:

                    class Client < ActiveRecord::Base
                        def self.my_class_method
                        end
                        def my_instance_method
                        end
                    end

                    And then in your view:

                        <%= Client.my_class_method %>
                        <%= @client.my_instance_method %>

选项 2:

                    module MyModule
                        def my_method
                        end
                    end

                  Include the module in ApplicationHelper so it is available to all your views:

                    module ApplicationHelper
                        include MyModule
                    end

                    Then in your view you can call it easily:

                    <%= my_method %>

选项 3:

                    module MyModule
                        def my_method(amount)
                        end
                    end

                    In your model:

                    class Client < ActiveRecord::Base
                        include MyModule
                        def self.other_method(amount)
                          my_method(amount)
                        end
                    end     

                    Then in your view you can call it easily:

                    <%= Client.other_method(amount) %>  

选项 4: 或者您可以将辅助方法声明为类函数,并像这样使用它:

                    module Myhelper
                        def self.my_village
                          "bikharniyan kallan,Rajasthan,India"
                        end
                    end 

                  Then in your view you can call it easily:

                    <%= Myhelper.my_village %>  

选项 5: 在控制器中使用许多助手 助手=>

                        module Myhelper
                            def my_info
                              "my information is"
                            end
                        end

                        module Myhelper1
                            def my_village
                              "bikharniyan kallan,Rajasthan,India"
                            end
                        end

                    ApplicationHelper=> 

                        module ApplicationHelper
                            include Myhelper
                            include Myhelper1
                        end

                    ApplicationController

                        class ApplicationController < ActionController::Base
                            include ApplicationHelper
                        end 

                    YourController  

                        class YourController < ActionController::Base
                            def action
                              my_info
                              my_village
                            end
                        end

【讨论】:

  • 如果您只是逐字复制我的一部分答案,礼貌地说它来自我。
  • 我只是结合来自不同来源的所有方法以获取用户帮助
【解决方案4】:

此时,使用 rails 5,您可以简单地将常用方法推送到 application_record.rb

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

  def self.common_class_method
    # some awesome implement
  end

  def common_method
    # implement this
  end
end

然后在每个模型类中,您可以通过 YourClassName.common_class_method 调用 common_class_method

或致电common_methodYourClassInstance.common_method

【讨论】:

  • 使用这种方法,您可以将common_methodcommon_class_method 添加到应用程序中的每个模型。这通常不是您想要的,因此人们应该谨慎选择此选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多