写这个if语句会有更有效的方法吗? (清理代码)

时间:2016-09-27 19:27:38

标签: ruby-on-rails ruby

最初的想法是,如果用户写了一个生物,在他们的个人资料上显示它。否则,显示一条消息。

<% if @user.bio.present? %>
  <p class="user-bio"><%= @user.bio %></p>
<% else %>
  <% if @user == current_user %>
    <p class="user-bio">Press the green edit button and write something interesting about yourself.</p>
  <% else %>
    <p class="user-bio">Sorry, this user hasn't written anything about themselves yet.</p>
  <% end %>
<% end %>

然后我想到了一种改进此功能的方法。而不是让用户导航到他们的设置页面(设计/注册/编辑),让他们直接从他们的个人资料页面(用户/节目)编辑他们的生物。

为此,bio将是一个看起来像文本的输入字段,但当悬停或点击时,用户可以看到他们可以编辑文本。

所以我在下面制作了这个模拟版本,并为我的用户控制器添加了资源。但是我收到了最后一个else标记的错误。我是rails(和ruby)的新手,我认为这段代码非常混乱。有经验的人可以帮我写一个更好的if语句来解决同样的问题。我需要一个更清洁的解决方案。

    <% if @user.bio.present? %>
      <p class="user-bio"><%= @user.bio %></p>
    <% else %>
      <% if @user == current_user %>
        <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| %>
          <%= devise_error_messages! %>
            <div class="input-group">
              <%= f.text_field :bio, class: "form-control" %>
            </div>
            <div class="actions">
              <%= f.submit "Update", class: "btn-signin" %>
            </div>
      <% else %>
        <p class="user-bio">Sorry, this user hasn't written anything about themselves yet.</p>
      <% end %>
    <% end %>

2 个答案:

答案 0 :(得分:1)

您无需在第一个if内嵌套新的else块。

此外,正如@JoeC在评论中指出的那样,您需要为<% end %>结束form_for

<% if @user.bio.present? %>
  <p class="user-bio"><%= @user.bio %></p>
<% elsif @user == current_user %>
  <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, multipart: true }) do |f| %>
    <%= devise_error_messages! %>
    <div class="input-group">
      <%= f.text_field :bio, class: "form-control" %>
    </div>
    <div class="actions">
      <%= f.submit "Update", class: "btn-signin" %>
    </div>
  <% end %>
<% else %>
  <p class="user-bio">
    Sorry, this user hasn't written anything about themselves yet.
  </p>
<% end %>

如果您认为这仍然是太多标签汤,您可以将表单放在名为_form.html.erb的部分内部并进行渲染。这样,主视图模板就专注于显示内容的逻辑,而不是深入了解表单的细节。

<% if @user.bio.present? %>
  <p class="user-bio"><%= @user.bio %></p>
<% elsif @user == current_user %>
  <%= render 'form' %>
<% else %>
  <p class="user-bio">
    Sorry, this user hasn't written anything about themselves yet.
  </p>
<% end %>

我要指出的最后一件事是您可能想要切换第一次和第二次if测试。你的逻辑布局方式,用户在输入生物后就永远无法编辑它们。

答案 1 :(得分:1)

我同意Chris Peters的100%同意。您可以将表单代码放入名为partial:

的单独文件中

<强> 应用程序/视图/ YOUR_CONTROLLER_NAME / _form.html.erb

 <%= form_for(resource, as: resource_name, url: registration_path(resource_name), 
                        html: { method: :put, multipart: true }) do |f| %>

   <%= devise_error_messages! %>
     <div class="input-group">
       <%= f.text_field :bio, class: "form-control" %>
     </div>

     <div class="actions">
       <%= f.submit "Update", class: "btn-signin" %>
     </div>
 <% end %>

有关您可以在此处找到的部分内容的一些信息:http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

如果您决定遵循Chris的建议,您可以进一步转换代码:

<% if @user.bio.present? %>
  <p class="user-bio"><%= @user.name %></p>
<% else %>
  <%= render 'form' if @user == current_user %>
  <p class="user-bio">
    Sorry, this user hasn't written anything yet.
  </p>
<% end %>

Ruby If语句示例:Great Ruby Shorthands For If…Then…Else

您还可以考虑使用以下内容标记:

<% if @user.bio.present? %>
  <%= content_tag(:p, @user.name, class: "user-bio") %>
<% else %>
  <%= render 'form' if @user == current_user %>
  <% no_bio_msg = "Sorry, this user hasn't written anything yet." %>
  <%= content_tag(:p, no_bio_msg, class: "user-bio") %>
<% end %>

希望这会有所帮助。