如何告诉DataTable如何通过ActiveRecord处理关联的数据表?

时间:2012-08-03 21:56:35

标签: ruby-on-rails-3 datatables

我似乎无法找到这个简单需求的答案:如何告诉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

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

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'
...

应该使用服务器端处理来准备数据,但这会产生一个传递给DataTables中的jQuery的JSON数组。 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
...

肯定会欣赏这里的任何指示;感觉我没有地图或手电筒在丛林中迷路了!

谢谢, 里克凯西

1 个答案:

答案 0 :(得分:1)

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

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与此讨论无关。

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

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

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

约翰