无法编写方法

时间:2014-07-18 14:06:35

标签: ruby-on-rails

我试图编写一个定义,用作表单中选择字段的选项。

Miniature.rb
  has_many :manufacturers
  has_many :lines
end

Line.rb
  belongs_to :manufacturer
end

将@miniature添加到@line时,我希望下拉菜单只显示属于与@miniature对应的@manufacturer的@lines。

这是我的尝试

def mfr_lines
    @mfrs = @miniature.manufacturers.map
    @mfr_lines = @mfrs.lines.map
end

第一行似乎有效,它结合了所有@mini.manufacturers 我需要做的是获取EACH @manufacturer的所有行并将它们连接成一个数组。我无法解决如何进行EACH或如何加入它们的问题。尝试了许多可能的解决方案无济于事。任何帮助非常感谢。

它想在视图中最终像这样工作

<%= f.select :line_id, @mfr_lines, include_blank: true %>

2 个答案:

答案 0 :(得分:3)

@ hoffm的解决方案很好,但可以使用一点改进的版本:

def mfr_lines
  @lines = Line.where(manufacturer_id: @miniature.manufacturers.pluck(:id))
end

用于options_for_select (1)的选择:

f.select :line_id, options_for_select(@lines.map{|l| [l.name, l.id] }), include_blank: true

为什么它比@miniature.manufacturers.map(&:lines).flatten更好

  • manufacturers.map(&:lines)实际上在每个.lines上调用方法manufacturer(触发SQL查询)。如果您有10个,则会调用10次SELECT * FROM lines WHERE lines.manufacturer_id = <id>

  • Line.where(manufacturer_id: @miniature.manufacturers.pluck(:id))是并且将始终只有2个组合查询:

    # @miniature.manufacturers.pluck(:id) (2)
    SELECT id FROM manufacturers WHERE manufacturers.miniature_id = <@miniature.id> ;
    # This returns a list of IDs
    
    # Line.where(manufacturer_id: list_of_ids)
    SELECT * FROM lines WHERE lines.manufacturer_id IN (<list_of_ids>) ;
    

总体而言,以下Ruby on Rails代码:

Line.where(manufacturer_id: @miniature.manufacturers.pluck(:id))

触发以下SQL:

SELECT * 
  FROM lines 
  WHERE lines.manufacturer_id 
  IN ( SELECT id 
         FROM manufacturers 
         WHERE manufacturers.miniature_id = <@miniature.id> )

参考文献:

答案 1 :(得分:1)

在没有块的情况下调用map将返回一个枚举器,它听起来并不像您期望的那样。如果我理解你所追求的是什么,这就是要走的路:

def mfr_lines
  @miniature.manufacturers.map(&:lines).flatten
end

此代码检索与缩略图相关联的所有制造商的数组,然后将每个制造商的数组映射到其行的数组中。结果是一个行数组的数组,然后我们将它们展平以得到一系列可以迭代的行。