簡體   English   中英

清理腫的視圖

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM