干燥代码导致输出加倍

时间:2014-10-03 20:47:13

标签: ruby-on-rails ruby-on-rails-4

我正在制作简历申请表,列出我的工作经历,教育历史和其他责任。这是我自己的第一个rails应用程序,没有教程,但我所做的很多事情只是遵循相同的操作。所有代码都在这里:https://github.com/victorman/portfolio

快速摘要。我把我的应用程序弄了一下,然后开始工作了。但我有一个模板与视图的一部分具有完全相同的html,所以我用render :partial...替换了该部分。结果是以前的两倍html。以下是我对该应用所做的更详细的描述。


我制作了两个脚手架,一个用于乔布斯,一个用于分类。乔布斯拥有分类的外键。

我为Jobs视图列表提供了每个类别的链接。然后jobs#index控制器只查找该类别的作业表中的行。

然后我决定在那里抛出一些ajax,以便点击链接只会重新加载相关数据。我在jobs#index方法的末尾添加了respond_to。

def index
  #find which jobs to display based on category_id in the url params
  #if no category_id param is given default to 1
  unless params.has_key? :category_id
    @jobs = Job.find(:all, :conditions => {:category_id => 1})
  else
    @jobs = Job.find(:all, :conditions => {:category_id => params[:category_id]})
  end

  respond_to do |format|
    format.html
    format.js    #index.js.erb
  end
end

我创建了一个index.js.erb文件,用于检索新数据并替换旧数据。

var jobs = $("<%= escape_javascript(render(:partial => @jobs))%>").hide();
$("#jobs_table").replaceWith(jobs);
$("#jobs_table").fadeIn();

我添加了remote:true到作业index.html.erb文件中的链接。

<ul>
    <% Category.all.each do |category| %>
    <li><%= link_to category.name, { :controller => "jobs", :category_id => "#{category.id}" }, :class => "category_link", remote: true %></li>
    <% end %>
</ul>

我将模板放在显示作业的位置。它永远不会找到_jobs.html.erb所以我必须将它命名为_job.html.erb

<tbody id="jobs_table">
  <% @jobs.each do |job| %>
    <tr>
      <td><%= job.organization %></td>
      <td><%= job.location %></td>
      <td><%= job.details %></td>
      <td><%= job.start_date %></td>
      <td><%= job.end_date %></td>
      <td><%= link_to 'Show', job %></td>
      <td><%= link_to 'Edit', edit_job_path(job) %></td>
      <td><%= link_to 'Destroy', job, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
</tbody>

毕竟它有效但我仍然没有干掉代码,所以我删除了index.html.erb_job.html.erb的重复部分(如上所示)并将其替换为

<%= render :partial => @jobs %>

现在它给了我两个相同的<tbody>标签,其中id =“jobs_table”。为什么这会提供重复数据?

two tbody tags. guess where I live.

2 个答案:

答案 0 :(得分:1)

你需要修理很多......
在routes.rb中创建一个嵌套路由:

resources :jobs
resources :categories do
  resources :jobs
end

index.html.erb:

<h1>Listing jobs</h1>
<div>
  <ul>
    <% Category.all.each do |category| %>
      <li><%= link_to category.name, category_jobs_path(category), 
                class: "category_link", remote: true %></li>
    <% end %>
  </ul>
</div>
<table>
  <thead>
    <tr>
      <th>Organization</th>
      <th>Location</th>
      <th>Details</th>
      <th>Start date</th>
      <th>End date</th>
      <th></th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody id="jobs_table"><%= render partial: @jobs %></tbody>
</table>
<br/>
<%= link_to 'New Job', new_job_path %>

jobs_controller.rb的索引可以(应该)重构为:

class JobsController < ApplicationController
  def index
    @jobs = Job.where(category_id: params[:category_id] || 1)
    respond_to do |format|
      format.html
      format.js
    end
  end
end

并且index.js.erb响应也应该重构为:

$("#jobs_table").html("<%= escape_javascript(render partial: @jobs) %>")
$("#jobs_table").fadeIn()

有一些命名问题应该更加怀孕:

工作而不是jobs_table

类别而不是category_link
同时试图找到属于Category的1的作业是奇怪的。处理与ID为1的默认类别不同的​​响应(硬编码ID是您可以做的最糟糕的事情之一) “类别”列表周围的div是无用的(保持渲染的HTML细长且可读)。

答案 1 :(得分:0)

问题是由于不了解rails操纵单数与复数的关系。

自动调用render partial: @jobs@jobs中的每个元素转到部分_job.html.erb。但是由于@jobs.each do |job|,部分会再次遍历每个元素。

要修复此问题,请在渲染行中将@jobs替换为"jobs",并将_job.html.erb重命名为_jobs.html.erb。 或者,只需将@jobs替换为"job"并保留模板名称_job即可保存一个步骤,但这会强化错误的命名方案。

index.html.erb:

<tbody id="jobs"><%= render partial: "jobs" %></tbody>

index.js.erb的:

$("#jobs").html("<%= escape_javascript(render(partial: 'jobs'))%>")

现在它只是逐字搜索_jobs模板(_jobs.html.erb)并渲染一次,而不是转到名称的单数版本并多次渲染。