2

我似乎找不到这个简单需求的答案:如何告诉 Rails 以及 DataTables 相关的数据表?这是基于Railscast 340的。(Ryan Bates 警告说服务器端处理更复杂;确实如此!)

我在 Rails 方面还没有太多经验,所以我还在学习各种 find() 方法,用于使用 Active Record 告诉 ROR 相关数据;但我的任务的本质是在 index.html.erb 视图文件中显示基因型,其中视图中的棘手部分是:

  def index
     respond_to do |format|
      format.html
      format.json { render json: GenotypesDatatable.new(view_context) }
    end
  end

完整的 GenotypesDatatables 类见下文;这直接在 /app 文件夹下的一个新类中。

我需要显示/编辑来自三个模型的数据:基因型、gmarkers 和 gvision。我还需要显示来自 gsamples 和 gmarkers 的与基因型相关的两个模型的数据。

模型的构造如下:

class Gmarker < ActiveRecord::Base
attr_accessible :marker
has_many :genotypes, :dependent => :delete_all

...
class Genotype < ActiveRecord::Base
attr_accessible :allele1, :allele2, :run_date
belongs_to :gmarkers
belongs_to :gsamples
...
class Gsample < ActiveRecord::Base
belongs_to :gupload
has_many :genotypes, :dependent => :delete_all
attr_accessible :box, :labid, :subjectid, :well

从网络服务器的此错误消息输出中可以看出,问题在于没有获得正确的数据关联:...

CACHE (0.0ms) SELECT COUNT(*) FROM "genotypes"
Genotype Load (10.5ms) SELECT "genotypes".* FROM "genotypes" ORDER BY allele1 asc LIMIT 10 OFFSET 0
Completed 500 Internal Server Error in 255ms

NameError (undefined local variable or method `f' for #<GenotypesDatatable:0x9833ad4>):
app/datatables/genotypes_datatable.rb:24:in `block in data'
app/datatables/genotypes_datatable.rb:21:in `data'
app/datatables/genotypes_datatable.rb:14:in `as_json'
app/controllers/genotypes_controller.rb:7:in `block (2 levels) in index'
app/controllers/genotypes_controller.rb:5:in `index'
...

数据应该使用服务器端处理来准备,但这会导致一个 JSON 数组传递给 DataTables 中的 jQuery。JSON 数组在 DataTables 类中准备好:

class GenotypesDatatable
  delegate :params, :h, :link_to, to: :@view

  def initialize(view)
    @view = view
  end

  def as_json(options = {})
    # This is what feeds directly into DataTables
    {
      sEcho: params[:sEcho].to_i,
      iTotalRecords: Genotype.count,
      iTotalDisplayRecords: genotypes.total_entries,
      aaData: data
    }
  end

private

  def data
    genotypes.map do |genotype|
      [
        # Note: h is shorthand for html_escape
        h(Gmarker.find(f.gmarkers_id).marker),
        h(Gsample.find(f.gsamples_id).labid),
        h(Gsample.find(f.gsamples_id).subjectid),
        h(Gsample.find(f.gsamples_id).box),
        h(Gsample.find(f.gsamples_id).well),
        h(genotype.allele1),
        h(genotype.allele2),
        h(genotype.run_date)
      ]
    end
  end

  def genotypes
    @genotypes ||= fetch_genotypes
  end

  def fetch_genotypes
    genotypes = Genotype.order("#{sort_column} #{sort_direction}")
    genotypes = genotypes.page(page).per_page(per_page)
    if params[:sSearch].present?
      genotypes = genotypes.where("labid like :search or category like :search", search: "%#{params[:sSearch]}%")
    end
    genotypes
  end
...

肯定会感谢这里的任何指示;感觉就像我在没有地图或手电筒的情况下迷失在丛林中!

谢谢,里克凯西

4

1 回答 1

2

如你所知,我正在做类似的事情。我不会尝试更改可能会混淆问题的代码,而是将我的代码作为示例发布。我的表邻居包含关联。

class Neighbour < ActiveRecord::Base

  belongs_to :locality, :class_name => "Locality"
  belongs_to :neighbour, :class_name => "Locality"
  belongs_to :highway,  :class_name => "Highway"

  default_scope joins(:locality, :highway).order('localities.name')

end

我认为 default_scope 在这个讨论中是无关紧要的。

我认为是 NeighborsDatatable 类中的相关代码:

def data
  neighbours.map do |neighbour|
    [
     neighbour.locality.name,
     neighbour.neighbour.name,        
     neighbour.highway.name, 
     neighbour.distance,
     neighbour.id
    ]
 end

结尾

所以我不确定你需要做明确的发现。我的表格使用 DataTables 正确显示。希望这对另一个 ROR 新手有所帮助。

约翰

于 2012-08-06T09:42:10.040 回答