How much should I avoid computations in my views?

若如初见. 提交于 2020-03-05 03:02:09

问题


I am building an application where n users can talk to each other (like a messaging application) in public. Because you might want to have a different bio for each talk you do (for example a discussion about me regarding Ruby on Rails would need a different bio than one about Psychology) I have a Spkr model which has a User and a Tlk. The below code successfully means that on the users profile page, for each instance of them being a Spkr, the Tlk, and it's participants is visible with each Spkr's image (so if a Tlk has three participants, then all three images will be visible).

The setup is such where the default image is the User's image, but the Spkr can also customise their image by uploading one as a Spkr. I am worried that I am loading the front end with too much computation. Right now everything works... so is it ok? Or should I be limiting the computation happening when building views?

Thank you

<% @user.spkrs.each do |spkr| %>
  <%= link_to show_tlk_path(spkr.tlk) do %>
    <h4><%= spkr.tlk.title %></h4>
    <% spkr.tlk.spkrs.each do |speaker| %>
      <div class="tlk-tlking-image spkr-image image-spkr-<%= spkr.id %>"
        <% if speaker.image.present? %>
          style="background-image: url(<%= rails_blob_url(speaker.image) %>)"
        <% elsif speaker.user.image.present? %>
          style="background-image: url(<%= rails_blob_url(speaker.user.image) %>)"
        <% end %>
        >
      </div>
      <p><%= speaker.name %></p>
    <% end %>
  <% end %>
<% end %>

回答1:


It tends to be considered good practice to keep the view as free of 'back end' calculations as possible. These files are often worked on by front end developers who may not even know how to code ruby, so the less of it that is in the view the better. It's also just not where it belongs in rail's Model Controller View framework.

First of all the code you've put can be simplified to:

<% @user.spkrs.each do |spkr| %>
  <%= link_to show_tlk_path(spkr.tlk) do %>
    <h4><%= spkr.tlk.title %></h4>
    <% spkr.tlk.spkrs.each do |speaker| %>
      <div class="tlk-tlking-image spkr-image image-spkr-<%= spkr.id %>"
        style="background-image: url(<%= rails_blob_url((speaker.image  || speaker.user.image) %>)"
        >
      </div>
      <p><%= speaker.name %></p>
    <% end %>
  <% end %>
<% end %>

But as you say, if you want to handle this in a more appropriate place, I'd add a method to the Speaker class:

# app/models/speaker.rb
class Speaker << ApplicationBase
  def image_for_view
    image || user.image
  end
end

This will let you call speaker.image_for_view which I think reads nicely in the view file itself.




回答2:


Along with the great answer let me just add something that might help you to make views more clear. Might not be relevant to your question directly but might help you to get some idea how you can make views beautiful.

The first thing to make views look good are helpers. Though rails provide helpers for every controller, helpers are global meaning it can be used anywhere in any views. So, global formatings should be done with helpers. Like if you want a date formatter that needs to be used in a lot of view files, you can create a helper called date_helper.rb in app/helpers and put you desired date formatting -

module DateHelper
  def formatted_date(date)
    date.strftime([%m/%d/%Y')
  end
end

Next is what rails people like to call a Presenter pattern. This is helpful when you don't want some logic to be shared across all views. Some logic that doesn't feel like belongs in controller or model are put there to make views readable. Suppose you have a view like below which is a bit messy -

<p>
  Post title: <%= post.title.gsub("forbidden word", "") %>
  <%= link_to "Read post", post, class: "w-75 p-3 text-#{post.draft? ? "orange" : "green"} border-#{post.draft? ? "orange" : "green"}" %>
</p>

To make this more beautiful you can create a presenter class named post_presenter.rb which should reside in app/presenters and write some code like -

class PostPresenter
  def initialize(post)
    @post = post
  end
  def title_without_forbidden_words
    @post.title.gsub("forbidden word", "")
  end
  def css_color
    @post.draft? ? "orange" : "green"
  end
end

and in the view -

<% presenter = PostPresenter.new(post) %>
<p>
  Post title: <%= presenter.title_without_forbidden_words %>
  <%= link_to "Read post", post, class: "w-75 p-3 text-#{presenter.css_color} border-#{presenter.css_color}" %>
</p>

Such way a view might be more clear and also it can be lifesaver for frontend developers. This are the best two methods I found till now that makes a rails view beautiful which I always try to use.

Examples are taken from rubyguides website. Thanks to them,



来源:https://stackoverflow.com/questions/59694064/how-much-should-i-avoid-computations-in-my-views

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!