1

我的 Ruby-on-Rails 应用程序(我继承的第一个应用程序)中不断出现同样的问题。我有一个管理仪表板,其中视图迭代用户并将有关他们的一些数据放在一个 html 表中,每个用户一行。目前,我有视图在嵌入式 ruby​​ 中运行迭代,并在用户身上查找数据,有时对其进行处理,然后在迭代时将其逐行放入表中。

我对 Rails 很陌生,但似乎让程序从视图中执行如此多的数据库调用似乎破坏了 MVC 模型,而且不是很安全。我现在正在尝试使用我将从我们的支付处理公司(Stripe)调用的一些数据,并且从视图中这样做似乎非常不安全。具体来说,我计划根据他们提供的邮政编码添加一个包含客户位置的列。这需要调用 Stripe 以获取与其帐户关联的信用卡。

这就是问题所在。我看到了三种可能的方法,其中只有一种有效(但我认为这是错误的,所以我希望你能告诉我另一种方法。)

  1. 迭代控制器中的用户。获取所需的数据,然后用它做一些事情,让我把它带到视图中。遍历视图中的用户,从控制器中获取仅与该用户关联的数据,并为每个用户创建一个表行。同样,不知道该怎么做。
  2. 迭代控制器中的数据,并以某种方式将数据提供给它知道它正在接收数据的视图,并且它应该将每个迭代放在一行中(并将迭代中的每个项目放在一个单元格中。这可能吗?
  3. 我现在在做什么:在控制器中什么都不做,除了为我的所有用户创建一个局部变量,@users=User.all在视图中做所有事情。

现在,视图中的代码(对于其中一个示例。我在几个视图中多次发生这种情况,在用户页面、用户和社区参与页面以及每个产品的另一个页面上访问我们的所有用户。 ) 看起来像这样:

<table id="table_of_users2">
    <thead>
        <th width="200px">First Name</th>
        <th width="200px">Last Name</th>
        <th width="200px">Email</th>
        <th width="200px">Number Representing Community Activity</th>
        <th width="200px">Favorites</th>
        <th width="200px">Comments</th>
</thead>
<tbody>
    <% @users.each do |user|%>
        <% @our_community_activity_number=0 %>
        <% @times_faved=0 %>
        <% @comments=0 %>
        <% user.engagements.each do |engagement| %>
            <% if engagement.our_community_activity==true %>
                <% @our_community_activity_number+=1%>
            <% end %>
            <% if engagement.favorite==true%>
                <% @times_faved+=1%>
            <% end %>
            <% if engagement.comment!="" || engagement.comment!=nil %>
                <% @comments +=1 %>
            <% end %>
        <% end %>
        <tr>
            <td width="200px"><%= user.first_name%> </td>
            <td width="200px"><%= user.last_name %></td>
            <td width="200px"><%= mail_to("#{user.email}")%></td>
            <td width="200px"><%= @our_community_activity_number %></td>
            <td width="200px"><%= @times_faved==0?0:@meals_faved %>
            <td width="200px"><%= @comments %></td>
        </tr>
    <% end%>
</tbody>
</table>

我该如何重写它以使其更安全,并且我可以安全地将他们的位置信息从支付处理公司添加到页面?我认为我不能以这种方式安全地做到这一点是否正确?

谢谢。我是 Rails 的新手,我一次又一次地遇到同样的问题。

4

2 回答 2

2

我看不出这有什么可怕的问题。视图中没有发生数据访问,但有一些逻辑。如果你想删除逻辑,你

UserDashboardModel = Struct.new(:first_name, :last_name, :email, :our_community_activity_number, :times_faved, :comments)

def dashboard
  @users = User.all.map do |user_record|
    UserDashboardModel.new.tap do |user|
      user.first_name = user_record.first_name
      user.last_name = user_record.last_name
      user.email = user_record.email
      user.our_community_activity_number = user_record.engagements.select(&:our_community_activity).count
      user.favorite = user_record.engagements.select(&:favorite).count
      user.comments = user_record.engagements.select{|e| e.comment.present?}.count
    end
  end
end

然后在视图中,它要简单得多:

<table> 
   <thead>
        <th width="200px">First Name</th>
        <th width="200px">Last Name</th>
        <th width="200px">Email</th>
        <th width="200px">Number Representing Community Activity</th>
        <th width="200px">Favorites</th>
        <th width="200px">Comments</th>
</thead>
   <tbody>
       <% @users.each do |user| %>
        <tr>
            <td width="200px"><%= user.first_name%> </td>
            <td width="200px"><%= user.last_name %></td>
            <td width="200px"><%= mail_to(user.email)%></td>
            <td width="200px"><%= user.our_community_activity_number %></td>
            <td width="200px"><%= user.favorite %>
            <td width="200px"><%= user.comments %></td>
        </tr>
    <% end%>
</tbody>
</table>

这是否更好?主观上——观点肯定更愚蠢。这是一个优点。不过,控制器更难推理——有一些方法可以解决这个问题,比如在某个地方用另一种方法构建你的 UserDashboardModel 数组。

于 2013-06-29T00:12:21.807 回答
0

Ruby 因其瘦控制器而臭名昭著,这不是一件坏事,它只是 active_model 应用程序倾向于设置的方式:)

你应该在你的模型中做很多这样的繁重工作,而不是你的视图或控制器。您应该向用户询问它的参与度指标,这是用户循环其参与度并计算出 our_community_activity_number、times_faved 和评论的地方。

于 2013-06-28T20:49:37.327 回答