我遇到了同样的问题,这个问题一直出现在我的Ruby-on-Rails应用程序中(我的第一个应用程序,我继承了)。我有一个管理仪表板,其中视图迭代用户并将一些关于它们的数据放在一个html表中,每个用户一行。目前,我有一个视图在嵌入式ruby中运行迭代,并查找用户的数据,有时处理它,并在迭代时逐行放入表中。
我对rails非常陌生,但似乎让程序从视图中执行了大量的数据库调用,这似乎打破了MVC模型,并且不是很安全。我现在正在尝试使用我将从我们的支付处理公司(Stripe)调用的一些数据,看起来从View中这样做是非常不安全的。具体来说,我打算根据他们给出条带的邮政编码添加一个包含客户位置的列。这需要为与其帐户关联的信用卡调用Stripe。
这是问题所在。我看到有三种可能的方法,只有一种方法可行(但我认为这是错误的,所以我希望你能用另一种方式告诉我。)
@users=User.all
中创建局部变量外,在Controller中不执行任何操作,在视图中执行所有操作。现在,视图中的代码(针对其中一个示例。我在多个视图中多次发生这种情况,访问用户的所有用户作为客户页面,用户和社区参与页面以及另一个页面每个产品。)看起来像这样:
<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的新手,我一次又一次地遇到同样的问题。
答案 0 :(得分: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数组。
答案 1 :(得分:0)
Ruby以其瘦控制器而臭名昭着,它只是active_model应用程序倾向于设置的方式并不是坏事:)
你应该在你的模型中做很多繁重的工作,而不是你的观点或控制器。您应该向用户询问它的engagement_metrics,这是用户循环访问它的位置,并找出our_community_activity_number,times_faved和comments。