【问题标题】:Ruby on Rails access data through multiple joining tablesRuby on Rails 通过多个连接表访问数据
【发布时间】:2020-11-11 15:27:37
【问题描述】:

我有 5 张桌子(最简单的缩减),中间有 3 张桌子。

       /   sample   \
      |              |
chart -   compound   -  results
      |              |
       \ run_method /

每个图表都有一个样本、复合和 run_method。

每个结果都有一个样本、化合物和 run_method。

我想获得与图表的 3 个连接匹配的所有结果...

最简单的方法是什么?

class Chart < ApplicationRecord
  belongs_to :sample, inverse_of: :charts
  belongs_to :compound, inverse_of: :charts
  belongs_to :run_method, inverse_of: :charts
end

class Result < ApplicationRecord
  belongs_to :sample, inverse_of: :results
  belongs_to :compound, inverse_of: :results
  belongs_to :run_method, inverse_of: :results
end

class Sample < ApplicationRecord
  has_many :results, inverse_of: :sample
  has_many :charts, inverse_of: :compound
end

etc.

我已经尝试使用 Arel 来获取数据:

chart = Chart.arel_table
results = Result.arel_table
run_method = RunMethod.arel_table
sample = Sample.arel_table
compound = Compound.arel_table

results_join = results.join(sample).on(results[:sample_id].eq(sample[:id]))
                      .join(compound).on(results[:compound_id].eq(compound[:id]))
                      .join(run_method).on(results[:run_method_id].eq(run_method[:id]))
                      .join(chart).on(chart[:sample_id].eq(sample[:id])
                                      .and(chart[:compound_id].eq(compound[:id]))
                                      .and(chart[:run_method_id].eq(run_method[:id])))
@allresults = Result.joins(results_join.join_sources)
  .where(chart[:id].eq(params[:id]))

这获得了预期值,但现在显然没有实际使用 ActiveRecord 模型,因此错过了任何默认范围。

在我添加的图表模型中:

has_many :results, -> { where('results.run_method_id = run_methods.id and results.compound_id = compounds.id') }, through: :sample

我可以使用以下方法获取数据:

Chart.joins(:run_method).joins(:compound).includes(:run_method).includes(:compound).joins(:results).includes(:results).first.results

但这仍然没有真正使用模型之间的连接(样本除外)。

有没有办法在 ActiveRecord 和模型中执行此操作?

【问题讨论】:

  • 你没有任何成功的常规方式Result.joins(:sample)...
  • 问题更多是关于如何从图表中获取结果,这取决于匹配表之间的所有 3 个:Chart.joins(sample: :results).joins(compound: :results).joins(run_method: :results).find(1) 例如连接到“结果”表的 3 个不同副本.如果有一种方法可以在具有 3 个不同键的模型中使用“通过:”,我也许可以直接加入它
  • 我可以使用chart=Chart.find(1); Results.joins(:sample).joins(:compound).joins(:run_method).where("samples.id = ? and run_method.id = ? and compound.id = ?', [chart.sample_id, chart.run_method_id, chart.compound_id]) ...但我真的不认为这会简化解决方案。我想要的是“chart.results”等价物

标签: ruby-on-rails rails-activerecord ruby-on-rails-6


【解决方案1】:

我最终在 Chart 模型中创建了一个对 Result 对象的 def 调用:

在chart.rb中:

def results
  Result.where(compound: compound, run_method: run_method, sample: sample)
end

它可以工作,而且速度很快,不需要大量的 Arel 或记住要包含/加入的最小表。

我不需要反向“加入”,所以我认为这是安全的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 2021-07-09
    相关资源
    最近更新 更多