根据 db 值创建动态关联

Posted

技术标签:

【中文标题】根据 db 值创建动态关联【英文标题】:Create dynamic association according to db values 【发布时间】:2013-10-28 09:51:19 【问题描述】:

我想在 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

如果没有更好的可能。

【问题讨论】:

【参考方案1】:

您可以轻松地向 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 关联。

【讨论】:

感谢您的回复,但我的问题有点复杂。我不知道汽车有哪些颜色,因为它们可以在创建新记录时选择。 我需要按颜色对汽车进行分组。所以我不能将颜色传递给控制器​​,但我需要让所有汽车按颜色划分。我希望每种颜色都有一个关联(或虚拟属性)。 你的颜色是如何定义的,新的颜色是如何在运行时添加的?如果没有,您可以使用named scopesgroup_by 获得所需的所有工具。如果你真的想有关联,为什么不在一个颜色数组上循环并在这个循环中动态建立关联呢? 是的,可以在运行时添加颜色。所以,解决方案就像我的更新中的循环。谢谢 @macsig 我认为当进程开始时,循环只会被评估一次。所以它只会拾取启动或重新启动时出现的颜色。您可以将Car.all.map(&amp;:color).uniq 缩短和加速到Car.pluck(:color).uniq(这不会将所有汽车记录加载到内存中)。【参考方案2】:

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

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

【讨论】:

以上是关于根据 db 值创建动态关联的主要内容,如果未能解决你的问题,请参考以下文章

PySpark:是不是有可能根据非 Null 值创建动态数量的 DataFrame

根据使用 Javascript 选择的组合框动态添加表单字段

根据模板值动态设置 CSS 属性

从 SQLite DB 动态创建 ListView 行

Django 权限管理-后台根据用户权限动态生成菜单

sql语句大全(db2oraclemysqlsql server)