在 Ruby on Rails 项目中将“关注点”存储在哪里? (轨道 5.2+)

Posted

技术标签:

【中文标题】在 Ruby on Rails 项目中将“关注点”存储在哪里? (轨道 5.2+)【英文标题】:Where to store 'concerns' in a Ruby on Rails project? (Rails 5.2+) 【发布时间】:2020-03-26 11:31:43 【问题描述】:

我对 RoR 还很陌生。我花了一个下午阅读模块(用作关注点)。我还没有找到一篇描述使用includeextend 方法查找的文件路径的好文章(如果includeextend 是方法?)。

我发现的最具体的例子在这里:Ruby On Rails - Using concerns in controllers。这让我觉得如果我想在我的Foo 模型中包含'Bar' 模块,我会在我的models/ 目录中创建一个concerns/ 目录,并在此文件夹中创建一个'Bar' 模块文件。

# in models/concerns/bar.rb
modlue Bar
  # do I need this???
  extend ActiveSupport::Concern

  def speak_bar
    puts "model module bar!"
  end
end

# in models/foo.rb
class Foo < ApplicationRecord
  include Bar
end

# I could then perform:
Foo.new.speak_bar
=> "model module bar!"

如果我想在我的 Foo 控制器中包含一个 Bar 模块,我会这样做:

# in controllers/concerns/bar.rb
modlue Bar
  # Again, do I need this???
  extend ActiveSupport::Concern

  def speak_bar
    return "controller module bar!"
  end
end

# in controllers/foo.rb
class FoosController < ApplicationController
  include Bar

  def make_bar
    @bar = speak_bar
  end
end

# I could then use @bar in my views (anywhere else?) as <%= @bar %> and get it to output 
=> "controller module bar!"

问题总结:

就文件路径而言,上述理解是否正确?

我是否需要使用extend ActiveSupport::Concern 行才能使用此路径系统?

includeextend 是方法吗?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

the file path that using include or extend Rails 在开始自动加载很多东西时会发挥一些神奇的作用,因此您以后调用“Bar”时不必担心。这个演讲真的有助于理解为什么你可以在 Rails 模型中做 include Bar 而无需过多思考 https://www.youtube.com/watch?v=I0a5zv7uBHw

通常,您希望 /app/models/concerns 中的模型相关问题和 /app/controllers/concerns 中的控制器相关问题,但这只是出于组织目的,即使您使用 /app/whatever/concerns,rails 也会自动加载它们,所以要小心名称冲突。

如果你想使用 Concerns 提供的语法糖,你需要扩展 ActiveSupport::Concern,但最后它们只是可以包含的模块。 https://api.rubyonrails.org/classes/ActiveSupport/Concern.html 看看这个例子,关注点只是编写模块的一种方式,以使用更友好的通用 Rails 模式语法来共享行为。

extend是对象https://docs.ruby-lang.org/en/2.6.0/Object.html#method-i-extend的一个方法 include 是 Module https://docs.ruby-lang.org/en/2.6.0/Module.html#method-i-include 的一个方法(并且 Module 继承自 Object 的 extend

【讨论】:

【参考方案2】:

您应该始终使用 Rails 提供的关注点库扩展您的关注点模块。

路径通常是app/models/concerns/file.rb 用于模型问题,app/controllers/file.rb 用于控制器等。

如果您特别有跨越控制器和模型分离的逻辑,请考虑将其放在 lib 中,并将 lib 添加到您的自动加载路径中。

includeextend 是方法。大多数东西(几乎所有)都是 ruby​​ 中的对象。所以几乎所有的操作都是对象上的方法。

【讨论】:

感谢您的回答。在哪里更新自动加载路径? 我会在 application.rb 文件中这样做。但是,如果您只想在特定环境中使用此功能,则可以在您的 development.rb 或 production.rb 文件中执行此操作。【参考方案3】:

concerns 默认从 rails v4+ 开始由 rails 自动加载。您可以阅读 DHH 撰写的 article,以大致了解关注点的作用以及它试图解决的问题。

但是,要确定您所在的 scope 以及方法中的 self 变得相当复杂。查看 Ryan Bates 撰写的 video,了解 concerns 的问题。

为了解决问题的某些部分,我通常将关注点嵌套在一个文件夹中,并通过提供class 来引用它。例如

# app/models/concerns/user/authentication.rb

class User
  module Authentication
    extend ActiveSupport::Concern
    # stuff
  end
end

并包含在model

# app/models/user.rb

include Authentication

在我看来,关注点分离有助于隔离您的方法。例如,您可以以类似的方式创建Filterableconcern,并将其与您的其他models 隔离。

【讨论】:

以上是关于在 Ruby on Rails 项目中将“关注点”存储在哪里? (轨道 5.2+)的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails,将项目范围的单引号转换为双引号

如何在 ruby​​ on rails 中结合救援多个异常?

六个最酷的Ruby on Rails项目

ruby on rails (项目开始准备一)

Ruby on Rails全栈课程5.2 项目上线--在云服务器上配置Ruby On Rails环境

Ruby on Rails 中一个共享视图的两个控制器