【问题标题】:How do I get a relation for a model that belongs_to another model in rails如何获得一个模型的关系,该模型属于 Rails 中的另一个模型
【发布时间】:2016-05-10 11:13:41
【问题描述】:

我有两个模型:OptionAnswer。一个选项has_many :answers 和一个答案belongs_to :option。我有一个名为@answers 的变量:

@answers = Answer.where(content: 'a')

我现在需要获得与@answers 相关的所有选项的关系。我试过了:

@options = @answers.joins(:option)

但这会返回一个答案数组,而不是选项。如何从@answers 获得选项关系?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 model-view-controller activerecord rails-activerecord


    【解决方案1】:

    只需调用option 方法:

    @answers = Answer.where(content: 'a').map(&:option)
    

    【讨论】:

    • 这对关系不起作用。它返回一个数组,但我需要它返回一个关系
    • 谢谢乔希。我编辑了我的第一条评论以回复您的新答案。
    【解决方案2】:
    Option.joins(:answers).where(answers: { content: 'a' })
    

    或效率较低:

    Option.joins(:answers).where(answers: { id: @answers.pluck(:id) })
    

    或者不加入:

    Option.where(id: @answers.pluck(:option_id).uniq)
    

    或者在 Answer 类上使用范围并合并:

    scope :with_content ->(content) { where(content: content) }
    
    Option.joins(:answers).merge(Answer.with_content('a'))
    

    【讨论】:

    • 谢谢,但我需要使用 @answers 变量。这很接近,但仍然没有这样做
    • 我得到了第二个选择的答案:NoMethodError: undefined method `pluck' for #<0x007fdf592c1880>
    【解决方案3】:

    如果您确实需要@answers,请这样做以获得更好的性能:

    @answers = Answer.where(content: 'a')
    @options = Option.where('id in (?)', @answers.map(&:option_id).uniq)
    

    这样你只需要 2 个查询(避免 n+1)

    【讨论】:

    • id 应该是 answers.id 这里。我也会用 pluck 代替 map。
    • 他告诉他需要@answers,当您进行采摘时,它将执行数据库查询以选择ID。如果您已经有一个带有 id 的数组,则不需要这样做。
    • 使用地图,您正在加载大量对象。如果你衡量表现,我很确定 pluck 会名列前茅。
    • 但是 Phillip 想要 @answers 数组,所以你已经拥有了内存中的所有对象。在使用已经实例化的对象或进行新的数据库查询之间,我会选择不再访问数据库。
    • 更好的解决方案是@options = Option.where('id in (?)', Answer.where(content: 'a').pluck('distinct option_id')),但这样他就没有@answers
    【解决方案4】:

    可以吗

    @answers = Answer.where(content: 'a')
    @options = @answers.options.find(params[:id])
    

    ..或您想使用的任何选项参数。

    【讨论】:

      【解决方案5】:

      希望这会有所帮助:

      您可以急切加载与每个答案关联的“选项”

      @answers = Answer.where(content: 'a').includes(:option)
      

      然后在不运行查询的情况下获取选项,

      @options = @answers.map(&:option)
      

      请注意,这将返回一个活动记录关系数组,而不仅仅是一个数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-04
        • 2016-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多