更多 rails 部分在同一页面上

more rails partials on the same page

我有一个 rails 应用程序。我在 users/:id/show 页面上显示来自不同 类 的更多部分(用户、任务、对话、消息)。我在 users.controller 的 def show 动作中设置了所有实例变量(也适用于其他 类)。

好像有点重,有没有比这更好的方法呢? (我在 AJAX 调用中使用了@task 和@message。)

  def show
    @user = User.find(params[:id])
    if Task.between(current_user.id, @user.id).present?
      @tasks = Task.uncompleted.between(current_user.id, @user.id).order("created_at DESC").includes(:assigner).paginate(page: params[:page], per_page: 12)
      @task = Task.new
      if Conversation.between(current_user.id, @user.id).present?
        @conversation = Conversation.between(current_user.id, @user.id).first
        @messages = @conversation.messages.includes(:user)
        @message = Message.new
        respond_to do |format|
          format.html
          format.js { render :template => "tasks/update.js.erb", :template => "tasks/destroy.js.erb", layout: false }
        end
      end
    else
      redirect_to user_profile_path(@user)
    end
  end

更新:

users/show:

<%if @conversation%>
  <%= render 'conversations/show' %>
<% end %>

<tbody class="newtaskinsert2">
  <%= render partial: "tasks/task_between", collection: @tasks, as: :task %>
</tbody>

conversations/_show:

<div class="chatboxcontent">
  <% if @messages.any? %>
      <%= render @messages %>
  <% end %>
</div>
<div class="chatboxinput">
  <%= form_for([@conversation, @message], :remote => true, :html => {id: "conversation_form_#{@conversation.id}"}) do |f| %>
      <%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
  <% end %>
  <%= form_for([@conversation, @message], html: {class: "refile_form"}, remote: true) do |form| %>
      <span class="btn btn-success btn-sm btn-file">Choose file
      <%= form.attachment_field :message_attachment, direct: true, presigned: true, class: "choosefile" %></span>
      <%= form.submit "Send File", class: "btn btn-primary btn-sm btn-submit-refile", style:"display:none"%>
  <% end %>
  <span id="progresspercent"></span>
</div>

您只能在控制器中保留@user 实例变量,并且在局部使用:@user.tasks 而不是@tasks,@user.tasks.new 而不是@task 等。另请注意,您可以将参数传递给 partials (3.4.4 Passing Local Variables)

示例:

<%= render partial: "your_partial", locals: {tasks: @user.tasks} %>

更新:

用你的方式(从 class 调用方法而不是对象)你可以做类似的事情:

def show
    @user = User.find(params[:id])
    if Task.between(current_user.id, @user.id).present? 
    # @user.tasks.where(another_user_field_name: current_user).present? - looks more like Rails way
      @tasks = Task.uncompleted.between(current_user.id, @user.id).order("created_at DESC").includes(:assigner).paginate(page: params[:page], per_page: 12)
      @conversation = Conversation.between(current_user.id, @user.id).first      
      if @conversation
        respond_to do |format|
          format.html
          format.js { render :template => "tasks/update.js.erb", :template => "tasks/destroy.js.erb", layout: false }
        end
      end
      # Do not forget that if @conversation is not exists this code render views by default way
    else
      redirect_to user_profile_path(@user)
    end
  end


<%= render 'conversations/show' %>
<tbody class="newtaskinsert2">
  <%= render partial: "tasks/task_between"%>
</tbody>


<%if @conversation%>
  <div class="chatboxcontent">
    <%= render '_your_messages_partial', locals: {messages: @conversation.messages.includes(:user)}%>
  </div>
  <div class="chatboxinput">
    <%= form_for([@conversation, @conversation.messages.new], :remote => true, :html => {id: "conversation_form_#{@conversation.id}"}) do |f| %>
      <%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
    <% end %>
    <%= form_for([@conversation, @conversation.messages.new], html: {class: "refile_form"}, remote: true) do |form| %>
      <span class="btn btn-success btn-sm btn-file">Choose file
      <%= form.attachment_field :message_attachment, direct: true, presigned: true, class: "choosefile" %></span>
      <%= form.submit "Send File", class: "btn btn-primary btn-sm btn-submit-refile", style:"display:none"%>
    <% end %>
    <span id="progresspercent"></span>
  </div>
<% end %>

如果使用关系(@user.conversations 而不是 Conversation.between...等),您可以使此代码更短

我建议对您的视图使用缓存技术:

http://edgeguides.rubyonrails.org/caching_with_rails.html#fragment-caching http://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching

在性能仍然是您的问题的极端情况下,我建议开始对部分进行非规范化,直到您对性能满意为止。