RoR 视图中的数据传输对象 VS 域/ActiveRecord 实体

发布于 2024-08-22 21:48:24 字数 588 浏览 2 评论 0原文

我来自 .NET 背景,在这种情况下,一种做法是不将域/实体模型直接绑定到不太基本的 CRUD 式应用程序中的视图,其中视图不会按原样直接投影实体字段。

我想知道 RoR 中的做法是什么,默认的持久化机制是 ActiveRecord。我断言与演示相关的信息不应泄露给实体,但不确定真正的 RoR 负责人是否会这样做。

如果 DTO/每个视图模型是一种方法,那么您将如何在 Rails 中做到这一点?

你的想法?

编辑:

一些例子:
- 视图显示发票列表,其中一列包含唯一项目的数量。
- 可能执行欺诈交易的信用卡账户列表。为此,UI 需要将此行显示为红色。

对于这两种情况,列表不会显示实体的所有字段,仅显示列表中的一些字段(例如发票编号、交易日期、帐户名称、交易金额)

对于发票示例,发票实体没有映射“行项目数量”字段。由于性能原因,数据库尚未进行非规范化,它将在查询期间使用聚合函数进行计算。

对于信用卡账户示例,卡交易实体肯定没有“显示红色”或“IsFraudulent”不变量。是的,这可能是一个业务规则,但对于这个例子,这是一个表示问题,所以我想将其保留在我的域模型之外。

I'm coming from a .NET background, where it is a practice to not bind domain/entity models directly to the view in not-so-basic CRUD-ish applications where the view does not directly project entity fields as-is.

I'm wondering what's the practice in RoR, where the default persistence mechanism is ActiveRecord. I would assert that presentation-related info should not be leaked to the entities, not sure though if this is how real RoR heads would do it.

If DTOs/model per view is the approach, how will you do it in Rails?

Your thoughts?

EDIT:

Some examples:
- A view shows a list of invoices, with the number of unique items in one column.
- A list of credit card accounts, where possibly fraudulent transactions were executed. For that, the UI needs to show this row in red.

For both scenarios, The lists don't show all of the fields of the entities, just a few to show in the list (like invoice #, transaction date, name of the account, the amount of the transaction)

For the invoice example, The invoice entity doesn't have a field "No. of line items" mapped on it. The database has not been denormalized for perf reasons and it will be computed during query time using aggregate functions.

For the credit card accounts example, surely the card transaction entity doesn't have a "Show-in-red" or "IsFraudulent" invariant. Yes it may be a business rule, but for this example, that is a presentation concern, so I would like to keep it out of my domain model.

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

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

发布评论

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

评论(1

海螺姑娘 2024-08-29 21:48:24

一般来说,我会回答您的 AcitveRecord 对象可以包含任何字段,并且您仅在视图中显示您想要的内容。 Rails 脚本中有脚手架任务,但它只是创建一些设置模型、控制器和视图。当我使用 Rails 时,我根本不使用 ./script/generatescaffold 。相反,我只分别生成模型和控制器。我手动添加的视图部分。

ActiveRecord 仅将数据从数据库映射到一些好的对象。你用它做什么取决于你。

根据表示和业务规则之间的分离,我认为以下示例将使您清楚如何在 Rails 中处理它。

对于您的发票示例,我会这样创建一个视图:

<h1>Invoices</h1>
<table>
  <tr>
    <th>Invoice #</th>
    <th>Date</th>
    <th>Name</th>
    <th>No. of line items</th>
    etc
  </tr>
  <% @invoices.each do |invoice| %>
    <tr>
      <td><%= invoice.number %></td>
      <td><%= invoice.date.to_s %></td>
      <td><%= invoice.name %></td>
      <td><%= invoice.line_items.count %></td>
      etc.
    </tr>
  <% end %>
</table>

或者甚至将包含发票数据的行放入单独的部分中,并将其呈现在上面的视图中。我假设在您的模型中:

# Invoice model
has_many :line_items

现在让我们看一下信用卡示例。我会这样做:

# In CreditCard model add method
def fraudulent?
  #put here some logic that returns true or false
end

然后在您渲染此信用卡时在您的视图中:

<div <%= @credit_card.fraudulent? ? 'class="show_in_red"' : '' %>
   here you can show whatever you want
</div>

或者甚至为其创建助手:

# credit card helper
def add_show_in_red(credit_card)
  credit_card.fraudulent? ? 'class="show_in_red"' : ''
end

# in Rails 3 or earlier version with plugin that puts `h` method by default 
# your helper should have additional safe_html! call
def add_show_in_red(credit_card)
  (credit_card.fraudulent? ? 'class="show_in_red"' : '').safe_html!
end

并在视图中:

<div <%= add_show_in_red(@credit_card) %>>
   here you can show whatever you want
</div>

In general I would answer that your AcitveRecord object can contain any fields and you show in views only what you want. There is scaffolding task in rails scripts but it is only to create some setup model, controller and view. When I work with Rails I don't use ./script/generate scaffold at all. Rather I'm generating only model and controller separatly. The view part I add manualy.

ActiveRecord only maps data from database to some nice objects. What you do with it in view is up to you.

According to separation between presentation and business rules I think that fallowing examples would make it clear to you how to handle it in Rails.

For your invoice example I would create a view this way:

<h1>Invoices</h1>
<table>
  <tr>
    <th>Invoice #</th>
    <th>Date</th>
    <th>Name</th>
    <th>No. of line items</th>
    etc
  </tr>
  <% @invoices.each do |invoice| %>
    <tr>
      <td><%= invoice.number %></td>
      <td><%= invoice.date.to_s %></td>
      <td><%= invoice.name %></td>
      <td><%= invoice.line_items.count %></td>
      etc.
    </tr>
  <% end %>
</table>

Or even put a row with invoice data into separate partial and render it in above view. I assume that in your model you have:

# Invoice model
has_many :line_items

Now lets take a look on credit card example. I would do it like this:

# In CreditCard model add method
def fraudulent?
  #put here some logic that returns true or false
end

Then in your view when you render this credit card:

<div <%= @credit_card.fraudulent? ? 'class="show_in_red"' : '' %>
   here you can show whatever you want
</div>

Or even create helper for it:

# credit card helper
def add_show_in_red(credit_card)
  credit_card.fraudulent? ? 'class="show_in_red"' : ''
end

# in Rails 3 or earlier version with plugin that puts `h` method by default 
# your helper should have additional safe_html! call
def add_show_in_red(credit_card)
  (credit_card.fraudulent? ? 'class="show_in_red"' : '').safe_html!
end

and in view:

<div <%= add_show_in_red(@credit_card) %>>
   here you can show whatever you want
</div>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文