同一页面上的更多rails部分

时间:2015-12-02 22:50:57

标签: ruby-on-rails controller partial-views instance-variables

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

它似乎有点沉重,所以有比这更好的方法吗? (我正在使用@task和@message进行AJAX调用。)

  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

更新:

用户/显示:

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

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

对话/ _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>

2 个答案:

答案 0 :(得分:1)

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

样本:

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

更新

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

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 ......等),你可以使这段代码更短。

答案 1 :(得分:0)

我建议您使用缓存技术:

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

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