【问题标题】:Rails: filtering in has_many through associationRails:通过关联过滤has_many
【发布时间】:2015-01-27 16:07:41
【问题描述】:

我正在使用 Rails,我有这个模型

Job
  has_many :job_fonctions
  has_many :fonctions, through: :job_fonctions

JobFonction 
    belongs_to :job
    belongs_to :fonction 

Fonction
    has_many :job_fonctions
    has_many :jobs, through: :job_fonctions

我想要对显示页面中与当前作业具有相同功能的所有作业进行排序我已经在控制器中尝试过此代码

@related_jobss = Job
    .where('jobs.id != ?', @job.id)
    .where(:fonction_id=>@job.fonction)

但这给了我这个错误undefined methodfonction'for`,所以我想知道该怎么做?

这是我的视图代码

<% @related_jobs.each do |job| %>
    <%= link_to truncate(job.job_title, length: 45, escape: false).html_safe, job%>
<% end %>

【问题讨论】:

  • 因为是has_many关系,所以方法调用是@job.fonctions而不是@job.fonction,它会返回所有与@job相关的函数(不是单个id)。你想匹配@job 的所有功能还是只匹配一个?此外,fonction_id 应该在 JobFonction 中,而不是 Job,因此一旦您知道要查找的 fonction id/id,您将在 JobFonction 中查找它们以找到相应的 Jobs。
  • 我想匹配至少一个函数
  • 在控制台尝试:@job.fonctions.first.jobs。这应该会为您提供与@job 关联的第一个函数关联的所有作业的列表。

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


【解决方案1】:

通过创建一个新类来处理此逻辑,您将获得更好的体验。在您的模型目录中执行类似的操作,或者创建一个您自动加载的新服务目录。

#in controller, @fonction can be any Fonction object
@related_jobss = RelatedJobFinder.new(@job, @fonction).with_same_fonction


#this would be in it's own file related_job_finder.rb
class RelatedJobFinder

  def initialize(job, fonction)
    @job = job
    @fonction = fonction
  end

  def with_same_fonction
    remove_this_job_from(jobs)
  end

  private

  def jobs
    Fonction.find(@fonction.id).jobs
  end

  def remove_this_job_from(relation)
    relation.reject{|job| job.id == @job.id}
  end

end

【讨论】:

    【解决方案2】:

    编辑

    试试这个:

    @related_jobss = 
    Job.includes(:fonctions)
    .where('jobs.id != ?', @job.id)
    .where(fonctions: { id: @job.fonctions.pluck(:id) } ) 
    

    这应该为您提供所有Jobs 的工作不等于@job 的功能并且具有与@job.fonctions 相同的任何功能(一个、两个或所有)。

    我刚刚在我的应用程序中使用关系测试了此方法(我正在运行 Rails 4.1.6 仅供参考),并且我提取了与我列出的全部 id 数组仅部分匹配的项目。

    【讨论】:

    • 当我尝试这个时,我得到这个错误 PG::UndefinedColumn: ERROR: column jobs.fonctions does not exist LINE 1: ...fonctions"."fonction_id" WHERE (jobs.id != 5 ) AND "工作"."fo...
    • 那么@job.fonctions 给了你什么?所有工作相关的功能?
    • 工作 has_many :fonctions, through: :job_fonctions 所以@job.fonctions 必须给出工作的所有功能
    • 我知道这是它必须给你的,但我想知道当你在控制台。
    • 这个代码工作你能解释一下吗,唯一的限制是它只会返回具有所有功能而不是至少一个功能的相关工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多