用户可以创建一个DeliveryCost,指定title,cost_per_unit和时间。除了来自常数的定时之外,所有字段都是唯一的。这是一个相关的片段
# Table name: delivery_costs
#
# id :integer not null, primary key
# title :string(255)
# cost_per_unit :float
# created_at :datetime
# updated_at :datetime
# timing :string(255)
#
class DeliveryCost < ActiveRecord::Base
TIMING_INSTALL='Install'
TIMING_BREAKDOWN='Breakdown'
TIMING_TRANSPORT='Fuel'
TIMINGS=[TIMING_INSTALL,TIMING_BREAKDOWN,TIMING_TRANSPORT]
has_many :job_delivery_costs
然后将这些记录附加到JobDeliveryCost,可以输入更多字段。当用户从这些DeliveryCost标题中选择时,会为标题的每个实例显示时间......不是很漂亮
= f.input :delivery_cost_id, collection: DeliveryCost.order(:timing), :label_method => :timing, :value_method => :id, label: false
= f.input :delivery_cost_id, collection: DeliveryCost.order(:title), :label_method => :title, :value_method => :id, label: false
当然,我可以通过交付成本计时对交付成本标题进行分组,并将其应用于索引操作和下拉选择菜单操作。到目前为止我看过但看不到任何东西。我做了类似这样的事情来生成一个数组,
@delivery_cost = DeliveryCost.all
@delivery_cost = @delivery_cost.map {|c| c.timing}.uniq!
但是这只是创造一个新阵列而没什么价值......
我希望实现的一个小例子
--install--
foo
bar
foo
--breakdown--
blah
cat
--fuel--
jimmy
cricket
帮助!
# == Schema Information
#
# Table name: delivery_costs
#
# id :integer not null, primary key
# title :string(255)
# cost_per_unit :float
# created_at :datetime
# updated_at :datetime
# timing :string(255)
#
class DeliveryCost < ActiveRecord::Base
TIMING_INSTALL='Install'
TIMING_BREAKDOWN='Breakdown'
TIMING_TRANSPORT='Fuel'
TIMINGS=[TIMING_INSTALL,TIMING_BREAKDOWN,TIMING_TRANSPORT]
before_destroy :survive_if_jobs
has_many :job_delivery_costs
has_many :jobs, through: :job_delivery_costs
scope :install, -> { where(:timing => 'Install') }
scope :breakdown, -> { where(:timing => 'Breakdown') }
scope :fuel, -> { where(:timing => 'Fuel') }
validates :timing, inclusion: TIMINGS
validates :cost_per_unit, presence: true
validates :title, presence: true
def titles_by_timing
self.pluck(:timing, :title).group_by(&:first).map { |k, v| [k, v.map(&:last)] }
end
private
def survive_if_jobs
jobs.empty?
end
end
我从模型中得到意外的键盘结束错误,在他建议的数组采集方法中出现
错误消息
app / models / delivery_cost.rb:43:语法错误,意外的keyword_end,期待输入结束
Extracted source (around line #5):
@delivery_cost = DeliveryCost.all <this being line 5
@delivery_cost = @delivery_cost.map {|c| c.timing}.uniq!
# get_title
raise
添加了视图部分
%td
= f.input :delivery_cost_id, collection: DeliveryCost.order(:timing), :label_method => :timing, :value_method => :id, label: false
%td
= f.select :title, grouped_options_for_select(DeliveryCost.titles_by_timing)
%td
= f.input :cost_per_unit, label: false
%td
= f.input :hour_count, label: false
%td
= f.input :quantity, label: false
谢谢!
答案 0 :(得分:2)
您正在寻找的是grouped_options_for_select
,它将嵌套数组或数组哈希作为输入。我将演示两者。
向DeliveryCost
模型添加一个方法,该方法返回格式为的嵌套数组:
[["Install", ["foo", "bar"]], ["Breakdown", ["blah", "cat"]], ["Fuel", ["jimmy", "cricket"]]]
这是grouped_options_for_select
允许的格式之一。获得此格式的一种方法是:
def self.titles_by_timing
self.pluck(:timing, :title).group_by(&:first).map { |k, v| [k, v.map(&:last)] }
end
为了进一步解释上面的密集代码,我将逐个函数来完成它。 pluck(:timing, :title)
将返回delivery_timing
表格中每行的时间和标题。因此,使用您的示例,它将返回:
[["Install", "foo"], ["Install", "bar"], ["Breakdown", "blah"], ["Breakdown", "cat"], ["Fuel", "jimmy"], ["Fuel, "cricket"]]
然后,调用group_by(&:first)
将生成嵌套数组的散列,其中键是时序,值是所有时序 - 标题组合。使用您的示例:
{ "Install" => [["Install", "foo"], ["Install", "bar"]],
"Breakdown" => [["Breakdown", "blah"], ["Breakdown", "cat"]],
"Fuel" => [["Fuel", "jimmy"], ["Fuel, "cricket"]] }
调用最后一部分map { |k, v| [k, v.map(&:last)] }
,将每个哈希键值对转换为包含两个元素的数组。第一个元素是timing
,第二个元素是具有title
的{{1}}数组。使用您的示例(请注意,这与顶部的格式相同):
timing
我相信使用数组散列更简单一些。格式如下:
[["Install", ["foo", "bar"]], ["Breakdown", ["blah", "cat"]], ["Fuel", ["jimmy", "cricket"]]]
同样,在{ "Install" => ["foo", "bar"], "Breakdown" => ["blah", "cat"], "Fuel" => ["jimmy", "cricket"] }
模型中添加方法以获取按时间分组的标题
DeliveryCost
前两个步骤(def self.titles_by_timing
self.pluck(:timing, :title).group_by(&:first).each { |_, v| v.map!(&:last) }
end
和pluck
)与上面相同,但第三步采用嵌套数组的哈希值,即group_by
,并使其成为哈希值数组,其中每个数组只是该时间的标题列表。与上面相同:
{ "Install" => [["Install", "foo"], ["Install, "bar"]], ...
最后,在您看来,您可以使用{ "Install" => ["foo", "bar"], "Breakdown" => ["blah", "cat"], "Fuel" => ["jimmy", "cricket"] }
方法作为titles_by_timing
来获取标题。这适用于嵌套数组和数组哈希路由。
grouped_options_for_select