在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
如果没有更好的可能性。
答案 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