我有一个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>
答案 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
在极端情况下,性能仍然是一个问题,我建议开始对部分内容进行非规范化处理,直到您对性能感到满意为止。