根据db值创建动态关联

时间:2013-10-28 09:51:19

标签: associations ruby-on-rails-4

在Rails4应用程序中,我想创建动态关联。

我有以下型号:

class Pilot < ActiveRecord::Base
  has_many :cars
end

class Cars < ActiveRecord::Base
  belongs_to :pilot
end

汽车具有属性颜色,我想创建与可用颜色一样多的关联

例如,如果我有1辆红色轿车,2辆蓝色轿车和1辆绿色轿车,我想拥有我的飞行员模型

has_many :red_cars
has_many :blue_cars
has_many :green_cars

重点是我不知道将要拾取的颜色。

是否可以实施它?

感谢。

更新

我想我可能会做类似

的事情
#untested. Written just now
Car.all.map(&:color).uniq.each do |color|
  has_many "#{color}_cars".to_sym, -> { where(color: '#{color}') }, class_name: 'Car'
end

如果没有更好的可能性。

2 个答案:

答案 0 :(得分:0)

您可以轻松地向has_many关联添加条件(确保它们是第一个参数)。

class Pilot < ActiveRecord::Base
  has_many :cars
  has_many :red_cars, -> { where(color: 'red') }, class_name: 'Car'
end

您可以使用named scopes更好地组织这个。

class Pilot < ActiveRecord::Base
  has_many :cars
  has_many :red_cars, -> { red }, class_name: 'Car'
end

class Cars < ActiveRecord::Base
  belongs_to :pilot
  scope :red, -> { where(color: 'red') }
end

当您使用命名范围时,您始终可以@pilot.cars.red查找所有属于飞行员的红色汽车,如果这对您来说非常方便,则可能不需要自定义has_many :red_cars协会。

<强>更新

如果您事先不知道要检索的颜色,可以将动态条件传递到命名范围。

class Pilot < ActiveRecord::Base
  has_many :cars
end

class Cars < ActiveRecord::Base
  belongs_to :pilot
  scope :with_color, ->(color) { where(color: color) }
end

然后,您可以在控制器中选择@pilot.cars.with_color('red')@pilot.cars.with_color(params[:color])。在这种情况下,我不想创建硬编码的has_many :red_cars关联。

答案 1 :(得分:0)

另一种解决方法是将颜色视为enums Rails4 +将根据类型为枚举创建范围:

http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html