Ruby on Rails 与存储库模式?

发布于 2024-08-09 09:09:04 字数 334 浏览 5 评论 0原文

使用 ASP.Net MVC 后,我开始思考 Rails。我以前使用过 Rails,但有点生疏。 ASP.Net MVC 教程建议使用存储库模式隐藏数据层实现。这允许更轻松地进行单元测试的依赖注入,以及控制器与模型实现的良好解耦。

我记得 Rails 的控制器直接使用 Active Record 对象,并使用可以轻松设置和拆除的测试数据库进行单元测试。这解决了换出单元测试的需要,但在控制器中暴露如此多的 ActiveRecord 代码似乎仍然是一个坏主意。

所以我的问题是,这里最新的最佳实践是什么?真实的(不是模拟的)数据库是否仍然用于单元测试? Rails 开发人员是直接调用 ActiveRecord 还是抽象?

After working with ASP.Net MVC, it has me thinking about Rails. I worked with Rails prior, but am a little rusty. ASP.Net MVC tutorials recomment hiding data layer implementation with the repository pattern. This allows easiesr Dependency Injection for Unit Testing, and nice decoupling of the controller from the model implementation.

I remember Rails’ controllers using Active Record objects directly, and unit tests using test databases that could be setup and torn down with ease. That solves the need to swap out for unit testing, but still it seems like a bad idea to have so much ActiveRecord code exposed in the controller.

So my question is, what is the latest best practice here? Are real (not mocked) databases still used for unit testing? Do Rails developers call ActiveRecord directly, or an abstraction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

已下线请稍等 2024-08-16 09:09:04

我的经验是,Ruby on Rails 与 ActiveRecord 的集成如此紧密(在大多数情况下,它可以变得几乎完全透明),以至于开发人员经常在没有任何抽象的情况下使用它。

需要记住的是,存储库模式和活动记录模式都是在 Martin Fowler 的 企业架构模式 (如果你还没有读过……你应该读一下)。 Active Record 与 Rails 紧密集成。 Microsoft .NET 不会将您与某种模式联系起来...因此存储库模式被大多数开发人员采用。

My experience has been that Ruby on Rails integrates ActiveRecord so tightly (in most cases, it can become nearly completely transparent) that developers often use it without any Abstraction.

The thing to remember is that the Repository pattern and the Active Record pattern were both suggested in Patterns of Enterprise Architecture by Martin Fowler (which, if you haven't read it yet...you should). Active Record is tightly integrated in Rails. Microsoft .NET doens't tie you to a pattern...so the Repository pattern was adopted by the majority of the developers.

新雨望断虹 2024-08-16 09:09:04

我想知道 ActiveRecord 真的构成了“数据层”吗?毕竟,它的目的是(在相当合理的程度上)抽象实际的交互存储。如果我有一个继承自 ActiveRecord::Base 的模型,并且我在控制器中引用该模型,那么我真的在与数据层交互吗?

看看 存储库模式 的简要描述,我会说 的方法find_by_ 已经给了你它所描述的大部分内容,这很好,不是吗?好吧,抽象层是有漏洞的(可以更慷慨地说“务实”),因为如果需要的话我们可以更接近金属,例如 find_by_sql 就很明显表明:我们正在处理某种关系数据库。

我建议永远不要(或者也许我应该说“很少,而且不是没有极端的理由”——使用绝对值总是很棘手)将代码放入控制器中,以便可以推断正在使用的数据平台。它们都应该被推入模型中 - named_scope 在这里非常有用。对于复杂的结果,请考虑使用“演示”对象作为接口(Struct 和我个人最喜欢的 OpenStruct 在这里非常有用)。

虽然 ActiveRecord 是事实上的标准,因为它随 Rails 一起安装,但它并不是唯一的游戏。对于非 SQL 数据库,需要一些不同的东西,但即使在 SQL 域中也有 Datamapper(基于 同名 PoEAA 模式?)

在 Rails 3.0 中,挑选组件,例如 Yehuda 的 ORM,然后男孩们取消挑选并清理接口。

Does ActiveRecord even really constitute the "data layer", I wonder? After all, its purpose is to abstract (to a fairly reasonable extent) the actual interaction storage. If I have a model that inherits from ActiveRecord::Base and I reference that model in a controller, am I really interacting with the data layer?

Looking at a brief description of the Repository Pattern I'd say that methods of the find_by_ are already giving you much of what it describes, which is good, isn't it? OK, the abstraction layer is leaky (one might more generously say "pragmatic") in that we can go a lot closer to the metal if need be, and find_by_sql for example will pretty much make it obvious that we're dealing with a relational database of some kind.

I'd recommend never (or maybe I should say "rarely and not without extreme justification" - it's always tricky using absolutes) putting code in controllers that makes it possible to infer the data platform being used. It should all be pushed into the models - named_scope can be very useful here. For complex results, consider using "presentation" objects as the interface (Struct and my personal favourite OpenStruct can be very useful here).

While ActiveRecord is the de facto standard, given that it installs with Rails, it's not the only game in town. For non-SQL databases, something different is necessary, but even in the SQL domain there's Datamapper (is that based on the eponymous PoEAA pattern?)

In Rails 3.0 it's going to be a lot easier to pick and choose components such as the ORM as Yehuda and the boys unpick and clean up the interfaces.

雨巷深深 2024-08-16 09:09:04

无论哪种方式你都可以做到。大多数情况下,Rails 功能测试被编写为一直到数据库,其中数据是从固定装置填充的,正如您所描述的。

但模拟服务层调用并不罕见,例如:

User.expects(:find_by_id).with("1").returns(u);
get :show, :id=>"1"

...或类似的东西。事实上,我一直这样做,可以控制模型对象(或者也模拟它)。

You can do it either way. Most often, Rails functional tests are written to go all the way to the database, where data is populated from fixtures, as you describe.

But it's not uncommon to mock out the service layer calls, for example:

User.expects(:find_by_id).with("1").returns(u);
get :show, :id=>"1"

... or something like that. In fact, I do this all the time have control of the model object (or mock that out as well).

司马昭之心 2024-08-16 09:09:04

遵循 Rails 惯例总是会走上最不痛苦的记忆之路,所以建议这样做。

根据您对“真实”的定义...对于单元测试,我发现人们倾向于使用与其主站点相同的数据模式,并在测试运行之前/测试期间为数据库播种(通过使用 Factory Girl 、机械师或普通的固定装置),然后根据该数据运行测试。

Rails 开发人员直接对此数据调用 ActiveRecord,就像在现实世界中一样。

Folllowing Rails conventions always leads down the Path of Least Painful Memories, so it is advised.

Depending on your definition of "real"... For unit testing I've seen that people tend to use the same data schema as their main site, and seed the database before the tests are ran / during the tests (by using Factory Girl, Machinist or plain ol' fixtures) and then the tests are ran based on that data.

Rails developers call ActiveRecord directly on this data, as in the real world.

不乱于心 2024-08-16 09:09:04

控制器应该访问 MVC 中的模型。 Rails 就是为了避免一些企业界特有的不必要的抽象。

Controllers are supposed to access models in MVC. Rails is all about avoiding some of the needless abstractions that characterise the enterprise world.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文