[英]Cleaning up bloated views
我对Rails很陌生,所以我的倾向是夸大意见。 rack-mini-profiler显示了我的视图的2/3的加载时间和1/2的sql调用。 我正在寻找有关如何清理此问题的建议,以及一些有效的应用程序编码资源。
我有使用Trips(:city_id,:start_date,:end_date)的用户,这些Trips属于一个城市,属于一个国家。
控制者
# this grabs topics that are concidered genral
@feed = Topic.where(:city_id => current_user.trips.pluck(:city_id), :general_topic => true).uniq
# topics that are specific to a users trip time range
current_user.trips.each do |trip|
@feed += Topic.where("(general_topic = ? AND city_id = ?) AND ((start_date BETWEEN ? AND ? OR end_date BETWEEN ? AND ?) OR (start_date <= ? AND end_date >= ?))", false, trip.city_id, trip.start_date, trip.end_date, trip.start_date, trip.end_date, trip.start_date, trip.end_date).uniq
end
视图
<% @feed.each do |topic| %>
<% if topic.general_topic %>
<div>
<div>
<h3>
<%= link_to(topic) do %>
<%= topic.title %>
<% end %>
</h3>
</div>
<div>
<p><%= time_ago_in_words(topic.created_at) %> by <%= link_to topic.user.name, "#" %> about <%= topic.city.name %>, <%= topic.city.country.name %></p>
</div>
<div>
<p><%= topic.comments.size %> comments
<% if topic.comments.any? %>
(<%= time_ago_in_words(topic.comments.last.updated_at) %> ago)
<% end %></p>
</div>
</div>
<% else %>
<div>
<div>
<h3>
<%= link_to(topic) do %>
<%= topic.title %>
<% end %>
</h3>
</div>
<div>
<p><%= time_ago_in_words(topic.created_at) %> by <%= link_to topic.user.name, "#" %> in <%= topic.city.name %>, <%= topic.city.country.name %> <%= topic.start_date.strftime("%m/%d") %>-<%= topic.end_date.strftime("%m/%d") %></p>
</div>
<div>
<p><%= topic.comments.size %> comments
<% if topic.comments.any? %>
(<%= time_ago_in_words(topic.comments.last.updated_at) %> ago)
<% end %></p>
</div>
</div>
<% end %>
<% end %>
</div> <!-- end discussions -->
我知道这太可怕了。 但是我希望主题看起来像这样:
Topic.Title
topic.created_at "by" topic.user.name "about" topic.city.name "," topic.city.country.name
topic.comments.count (topic.comment.last.created_at)
为了使控制器或模型具有一些逻辑,我应该开始研究什么? 目前我的主题模型是:
class Topic < ActiveRecord::Base
belongs_to :user
belongs_to :trip
belongs_to :city
has_many :comments, :class_name => 'Comment', :foreign_key => :topic_id
default_scope { order("created_at DESC")}
为了提高速度和可读性,您可以做一些事情。
为了提高速度,请使用includes
将数据急于加载到控制器中。 例如,当您加载主题时,您也可以加载相关的注释:
@feed = Topic.where(:city_id => current_user.trips.pluck(:city_id), :general_topic => true).includes(:comments)
参见Rails 4:如何将include()与where()一起使用以检索关联的对象
通常,应尽量减少在视图中执行的数据库调用量:在控制器中完成时,所有这些操作都在一个地方完成,并且易于阅读和维护。
为了提高可读性,您可以将代码DRY(“不要重复自己”)。 查看if和else块的内容:它们几乎相同:如果topic不是.general_topic,则显示多一行。 为什么要重复这么多相同的东西? 您可以这样重写它:
<% @feed.each do |topic| %>
<div>
<div>
<h3>
<%= link_to(topic) do %>
<%= topic.title %>
<% end %>
</h3>
</div>
<div>
<p>
<%= time_ago_in_words(topic.created_at) %> by <%= link_to topic.user.name, "#" %> about <%= topic.city.name %>, <%= topic.city.country.name %>
<% unless topic.general_topic %>
<%= topic.start_date.strftime("%m/%d") %>-<%= topic.end_date.strftime("%m/%d") %>
<% end %>
</p>
</div>
<div>
<p><%= topic.comments.size %> comments
<% if last = topic.comments.last %>
(<%= time_ago_in_words(last.updated_at) %> ago)
<% end %>
</p>
</div>
</div>
<% end %>
请注意,我删除了topic.comments.any?
并用一些代码替换它以获得最后一个,并测试它是否存在。 这是语法糖(一旦发生了急切的加载),但我认为阅读起来会更清楚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.