Rails MVC-数据库搜索逻辑应该放在模型还是控制器中

马特·C

我想确保根据以下范例/模式正确组织/设计我的代码:

-模型视图控制器

-Rails Convention over Configuration

-瘦控制器,胖模型

我在这里按我认为最重要的顺序列出了它们。


我的问题

在阅读了几篇文章之后,特别是这篇文章这篇文章,我开始将控制器中的一些逻辑转移到我的模型中。

但是,即使阅读了更多类似MVC ThoughtModel vs. Controller分离关注点的文章/文章,我也无法决定是否将我的搜索逻辑(在以后的深入解释中)从控制器转移到模型中。还有更多未在此处列出。


场景

看法

两页:

  • 第一页包含一个文本字段和提交按钮,该按钮将POST请求中的用户输入作为参数传递给第二页。

  • 第二页只是在给定数组中渲染每个neatObject,我们称之为@coolList

控制器

  • 当第二页接收到POST请求时,将调用一个名为awesomeSearch的方法(感谢Rails路由)
  • awesomeSearch应该将用户的输入作为params [:searchString]可用,并与NeatObject模型一起使用以构建@coolList并使该列表可用于视图渲染。

模型

  • NeatObject从控制器和回报模型处理请求neatObjects回到那些控制器。

  • NeatObject模型定义之间的关系neatObjects在我们的数据库和其他表。

数据库

这些是根据我们的数据库组成每个neatObject的属性

  • id- int
  • 描述-字符串
  • 地址-字符串
  • date_created-时间戳

少了什么东西?

控制器如何与模型一起使用以获取用户输入的匹配项。

这是我感到困惑的部分。逻辑本身非常简单,但是我不确定哪些部分属于模型,哪些部分属于控制器。

  • 控制器是否应该将搜索字符串传递给模型,然后模型将结果传递回去?

  • 控制器是否应该向模型询问所有neatObjects,然后仅保留匹配的对象?

  • 解决方案兼有吗?

为了能够询问有关逻辑的特定位的问题,接下来,我将更详细地概述搜索过程。


深度搜索逻辑

这一过程涉及发现neatObjects匹配搜索字符串。如果不定义我们认为neatObjects匹配项就不可能继续进行下去为了使事情变得简单,我们将这样说:

如果搜索字符串包含在其说明或地址中,则neatObject会搜索字符串匹配,而忽略大小写和前导/结尾空格。

不能保证此定义是永久的。有几件事可能会改变我们的定义。我们可能需要测试更多的属性,而不仅仅是地址和描述,也许是数据库人员添加了一个新的重要属性,或者UI人员决定用户应该能够通过ID进行搜索。当然,与这些情况相反的是,我们需要从正在测试的属性列表中删除一个属性。在许多情况下,可能会改变我们对比赛的定义我们甚至可能必须添加或删除逻辑,或者如果决定只测试描述属性中的第一个单词,或者如果我们不再忽略大小写的话。

现在我们知道了定义匹配项的内容,并且知道我们的定义可能会更改。现在,我们可以更具体地定义搜索过程。

以下是步骤概述:

  1. 获取所有 neatObjects的引用
  2. 循环遍历每个neatObject,将每个单独的对象通过匹配测试
    1. 测试通过-在结果列表中添加/保留neatObject
    2. 测试失败-不要保留neatObject作为结果
  3. 使结果可用于视图

在显示可能的实现时,我将参考这些步骤。


执行

搜索功能可以在NeatObject模型或为视图提供服务的控制器中轻松实现

通常,我只会在控制器中编写所有逻辑,但是在了解了“瘦控制器,胖模型”设计之后,我认为它肯定适用于这种情况。在看到作者在模型中实现了“类似于搜索”功能之后,这篇文章特别让我考虑重新组织代码。作者的功能虽然不能处理用户输入,所以我想知道应该如何处理它。

在学习“ SCFM”之前,这就是我编写代码的方式:

控制器中的搜索逻辑:

#searches_controller.rb  

#This is the method invoked when second page receives POST request
def search
    @neatObjects = NeatObjects.all.to_a  

    @neatObjects.delete_if { 
        |neatObject| !matches?(neatObject, params[:searchString])
    }
end

def matches?(neatObject, searchString)
    if((neatObject.description.downcase.include? searchString.downcase) ||
       (neatObject.address.downcase.include? searchString.downcase))
        return true
    end
    return false
end

此方法获得其参考的所有的neatObjects通过调用(步骤1) 所有()NeatObject模型。它使用数组函数delete_if对每个neatObject进行匹配测试,并仅保留通过测试的对象(第2步)。由于我们将结果存储在服务于视图的控制器中的实例变量中,因此步骤3是自动自动完成的。

将逻辑放置在控制器中非常简单,但是考虑“ SCFM”设计模式时,这似乎非常不合逻辑。

我已经写了另一种选择,其中控制器发送用户输入到模型中的一个功能,它会返回的neatObjects匹配的输入。

模型中的搜索逻辑

#NeatObject.rb  

def self.get_matches_for(searchString)
    all.to_a.delete_if { |neighborhood| !matches?(searchString, neighborhood) }
end

def self.matches?(phrase, neighborhood)
    fields = [neighborhood.name, neighborhood.address]

    fields.map!(&:downcase)
    phrase.downcase!

    fields.each do |field|
        if (
            (phrase.include? field) ||
            (field.include? phrase)
           )
            return true
        end
    end

    return false
end  

此方法使用all()获取neatObjects的完整列表(步骤1)。与第一种方法一样,模型方法使用delete_if删除不符合特定条件(通过匹配测试)的数组元素(neatObjects)(步骤2)。在此方法中,为视图提供服务的控制器将在NeatObject模型上调用get_matches_for ,并将结果存储在实例变量中(步骤3),如下所示:@neatObjects = NeatObject.get_matches_for( params[:searchString] )

我确实认为该模型选项更干净,并且更易于维护,但是在下一节中,我将进行更深入的介绍。


顾虑

我可以看到模型方法和控制器方法的优缺点,但是我仍然不确定某些事情。

当我阅读了多次引用的文章时(就像我在这里一样),该模型定义了一个函数来返回最近添加的人员是非常合乎逻辑的。

控制器不必执行逻辑来确定是否最近添加了一个控制器不应该这样做是有道理的,因为这取决于数据本身。消息的“新近度”测试可能有完全不同的实现最近的人可能包括本周添加的人,而最近的消息只是今天发送的那些消息。

控制器应该只能够说出People.find_recentMessage.find_recent知道它得到了正确的结果。

  • find_recent方法也可以修改为采用时间符号并返回不同时间段的对象是否正确前-People.find_in_time( :before_this_month )Messages.find_in_time( :last_year )这是否仍然遵循MVC模式和Rails约定?

  • 控制器是否应该能够找到用户输入匹配的内容NeatObject.get_matches_for( searchString )

我认为匹配逻辑属于模型,因为在测试中使用了某些特定属性,这些属性根据数据而有所不同。对于不同的表,我们可能具有不同的属性,并且控制器绝对不应定义这些属性我知道控制器取决于模型,而不是模型,因此,即使其余逻辑在控制器中,模型也必须定义那些属性。

  • 如果模型定义了搜索时使用的属性,那么为什么不定义整个搜索功能呢?

上面的文字解释了为什么我认为模型应该处理搜索逻辑并表达我的大部分问题/疑虑,但是我确实有一些赞成其他选择的意见。

  • 如果模型仅与数据有关,那么如何证明将用户输入传递给数据呢?

如果控制器不处理搜索逻辑,它仍然需要将用户输入发送到模型。它会在发送之前将其清除吗?(删除前导/尾随空格并缩减字符串的大小写。)它是否只是发送从用户那里得到的确切输入?

  • 在哪里进行测试以确保输入内容不是恶意的?

我最大的一些问题:

  • 逻辑去向的答案在每种情况下都会改变吗?

如果搜索/匹配过程更简单,代码的位置会改变吗?例如,如果搜索更简单:

  • 如果要测试的唯一属性是地址,并且该地址不太可能更改,那么我们是否将使用控制器来处理搜索?

  • 如果我们要提供高级搜索功能,即用户决定要在搜索中包括哪些属性并控制其他一些因素,那么将有很多用户输入,仅用于定义搜索功能的参数。在模型中放置太多逻辑或用户输入吗?


综上所述

  • 如何始终确保将逻辑放在正确的位置(MVC)?
  • 对于我的特定情况,使用此数据和此搜索/匹配过程,应该如何组织代码?
  • 当您发现灰色区域或不确定逻辑所属位置时,可以遵循哪些准则?
弗朗西斯科·坎帕尼亚(FranciscoCampaña)

正如许多人在IT和生活中所认为的那样,这取决于规模和目标。

注意事项:

1)对于设计:如果您发现自己多次违反控制器中的DRY,可能是将逻辑移至模型的时候了。

2)为了性能:由于控制器的负载超过了模型的负载,因此控制器中的逻辑性能最差。

同样重要的是:除非您做的事情非常琐碎,并且db有数千行,否则不要使用db进行文本搜索。相反,请使用Solr,ElasticSearch,Sphinx等搜索引擎。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

用于在模型/数据库中搜索的Rails路由和动作逻辑

来自分类Dev

Rails 4在单独的控制器中搜索多个模型

来自分类Dev

Rails 4在单独的控制器中搜索多个模型

来自分类Dev

MVC中的编辑控制器不会更改数据库中的数据

来自分类Dev

从MVC页面中的模型(或控制器)中检索数据

来自分类Dev

从MVC页面中的模型(或控制器)中检索数据

来自分类Dev

MVC控制器-使用外键将图像存储在数据库中

来自分类Dev

在ASP.NET Core MVC中通过控制器从数据库读取信息

来自分类Dev

模型或控制器中的MVC变量?

来自分类Dev

Rails 控制器中的模型方法

来自分类Dev

MVC-是模型查看还是控制器查看?

来自分类Dev

MVC-是模型查看还是控制器查看?

来自分类Dev

MVC:此功能应在控制器中还是在模型中

来自分类Dev

Ruby on Rails,MVC,将派生数据放在哪里?

来自分类Dev

重构!如何在数据库查询中重新使用变量以在Rails控制器中检索数据

来自分类Dev

Rails:控制器中的回调将数据库中的属性从true更改为false

来自分类Dev

EF模型在MVC5中的数据库优先方法中放在哪里?

来自分类Dev

如何在Rails控制器中将数据“保存”到数据库?

来自分类Dev

从控制器Ruby On Rails将数据插入数据库吗?

来自分类Dev

Rails MVC体系结构-具有多个控制器源的视图

来自分类Dev

控制器中的Rails视图逻辑产生哈希/数组而不是打印数据

来自分类Dev

MVC4实体框架控制器数据库问题

来自分类Dev

.NET MVC-将数据库表从视图传递到控制器

来自分类Dev

如何从MVC控制器调用带有参数的数据库“选择”存储过程?

来自分类Dev

没有控制器的Rails更新数据库属性

来自分类Dev

从数据库追加到当前控制器的Rails链接

来自分类Dev

控制器的更新方法不更新我的数据库(Rails)

来自分类Dev

将逻辑移入控制器Rails

来自分类Dev

Rails-我应该在模型级别还是在数据库级别定义默认属性值?

Related 相关文章

  1. 1

    用于在模型/数据库中搜索的Rails路由和动作逻辑

  2. 2

    Rails 4在单独的控制器中搜索多个模型

  3. 3

    Rails 4在单独的控制器中搜索多个模型

  4. 4

    MVC中的编辑控制器不会更改数据库中的数据

  5. 5

    从MVC页面中的模型(或控制器)中检索数据

  6. 6

    从MVC页面中的模型(或控制器)中检索数据

  7. 7

    MVC控制器-使用外键将图像存储在数据库中

  8. 8

    在ASP.NET Core MVC中通过控制器从数据库读取信息

  9. 9

    模型或控制器中的MVC变量?

  10. 10

    Rails 控制器中的模型方法

  11. 11

    MVC-是模型查看还是控制器查看?

  12. 12

    MVC-是模型查看还是控制器查看?

  13. 13

    MVC:此功能应在控制器中还是在模型中

  14. 14

    Ruby on Rails,MVC,将派生数据放在哪里?

  15. 15

    重构!如何在数据库查询中重新使用变量以在Rails控制器中检索数据

  16. 16

    Rails:控制器中的回调将数据库中的属性从true更改为false

  17. 17

    EF模型在MVC5中的数据库优先方法中放在哪里?

  18. 18

    如何在Rails控制器中将数据“保存”到数据库?

  19. 19

    从控制器Ruby On Rails将数据插入数据库吗?

  20. 20

    Rails MVC体系结构-具有多个控制器源的视图

  21. 21

    控制器中的Rails视图逻辑产生哈希/数组而不是打印数据

  22. 22

    MVC4实体框架控制器数据库问题

  23. 23

    .NET MVC-将数据库表从视图传递到控制器

  24. 24

    如何从MVC控制器调用带有参数的数据库“选择”存储过程?

  25. 25

    没有控制器的Rails更新数据库属性

  26. 26

    从数据库追加到当前控制器的Rails链接

  27. 27

    控制器的更新方法不更新我的数据库(Rails)

  28. 28

    将逻辑移入控制器Rails

  29. 29

    Rails-我应该在模型级别还是在数据库级别定义默认属性值?

热门标签

归档