我们为什么需要它,这种模式可以解决什么问题?
有时我们有非常复杂的查询,直接在业务逻辑中使用。例如,可以在不同的控制器和服务对象中多次使用以下查询:
def index seasons = Season.joins(league: :country).where("countries.name = 'England'") render json: seasons end
这给我们带来了什么问题?
那么我们能做些什么来解决这个问题呢?
如果我们决定选择第一个选项并使用模型,有两种方法可以实现这一点:
# frozen_string_literal: true class Season < ApplicationRecord def self.by_league(league) where(league: league) end def self.by_status(status) where(status: status) end end Season.by_league(league) Season.by_status(status)
class Season < ApplicationRecord scope :by_league, -> (league) { where(league: league) } scope :by_status, -> (status) { where(status: status) } end Season.by_league(league) Season.by_status(status)
界面看起来不错,但我们仍然有一些问题。最重要的一个是违反了单一责任原则。模型变得太大太胖。我们一年可以获得100多种方法。因此,阅读、更改和维护将非常困难。拥有相同的接口会很好,但将该逻辑移动到单独的类中。
我们该怎么做呢?
创建查询对象模式就是为了解决此问题。
# app/units/queries/season.rb module Queries class Season class << self def by_league(league) ::Season.where(league: league) end def by_status(status) ::Season.where(status: status) end end end end Queries::Season.by_league(league) Queries::Season.by_status(status)
接口看起来不错,但有一个重要的问题 - 方法不可链接,我们每次都必须重复前缀。例如,如果你想写这样的东西,它是行不通的。::Season
Queries::Season.by_league(league).by_status(status)
那么,我们如何解决它呢?
Rails有一个有趣的方法。此方法允许您在模型上添加任何方法并将它们链接起来。例如,以下工作正常。
标签:数据,系统,系统架构,saas,实现数据,基础数据 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。