我有两个型号
class Portfolio < ActiveRecord::Base
has_many :project_types, dependent: :destroy
end
class ProjectType < ActiveRecord::Base
belongs_to :portfolio
end
ProjectType模型具有字段ptype
。它可以是网络&#39;或者&#39; mobile&#39;等
我怎样才能获得所有网络&#39;或者&#39; mobile&#39;使用范围的投资组合?
答案 0 :(得分:3)
为您的模型添加适当的范围:
# in models/project_type.rb
class ProjectType < ActiveRecord::Base
belongs_to :portfolio
scope :web, -> { where(ptype: 'web') }
end
要加载类型为web
的投资组合,只能在控制器中使用该范围并加入:
# in the controller
@web_portfolios = Portfolio.joins(:project_types).merge(ProjectType.web)
答案 1 :(得分:3)
您可以为两者设置明确的范围,或者您可以根据ptype选择一个范围,或者可以为数据库中的每个唯一ptype编程范围。如果你要添加各种不同的&#34; ptypes&#34;您可以执行以下任何操作,这将为您提供处理任何&#34; ptypes&#34;的范围:
scope :ptype, -> (ptype) { where(ptype: ptype) }
称为:
ProjectType.ptype('web')
或
class ProjectType < ActiveRecord::Base
self.pluck(:ptype).each do |ptype|
scope ptype.gsub(/\s+/,"_").downcase.to_sym, -> { where(ptype: ptype) }
end
end
我不推荐这个,我也不建议为每个&#34;字符串&#34; (例如ProjectType.web或ProjectType.mobile)。最佳平衡是将字符串值传递到范围内,以检索您要查找的内容。只是我的观点,我确定其他人对此有不同看法。
说实话,我认为ptype字段对于枚举器来说已经成熟 - 这将使代码更清晰,并定义该字段实际期望的内容,而不是允许任意字符串随机放置在那里。如下所示:
class ProjectType < ActiveRecord::Base
enum ptype: [:web, :mobile]
scope :ptype, -> (ptype) { where(ptype: self.ptypes[ptype] }
end
并且如此调用:
ProjectType.ptype(:web)
我认为这里或上面提到的这些解决方案中的任何一个都不再是&#34;正确&#34;,除了元编程解决方案为每个字符串生成一个范围存储在数据库中的ptype字段。
最后,这是您的投资组合的范围:
class Portfolio < ActiveRecord::Base
scope :by_ptype, -> (ptype) { joins(:project_type).merge(ProjectType.ptype(ptype) }
end
并且这样称呼:
Portfolio.by_ptype(:web)
答案 2 :(得分:2)
你可以这样做
class Portfolio < ActiveRecord::Base
has_many :project_types, dependent: :destroy
scope :ptype, -> (p_type) { includes(:project_types).where(project_types: {ptype: p_type}) }
end
你可以致电
Portfolio.ptype('web')
答案 3 :(得分:1)
遵循Rails 4.1方法我会认为我的ptype字段是一个枚举并写下:
class ProjectType < ActiveRecord::Base
belongs_to :portfolio
enum ptype: { web: 'web', mobile: 'mobile' }
end
这会给你:
ProjectType.web
ProjectType.mobile
根据ptype获取对象的范围,但也会提供其他有用的方法,如:
@projectType.web?
@projectType.web!
请参阅文档:http://api.rubyonrails.org/v4.1/classes/ActiveRecord/Enum.html
在这里你问如何检索“web”Portfolio
,我想你的意思是“所有投资组合至少有一个项目类型为ptype'Web'。
然后我会写一些像:
Portfolio.joins(:project_types).merge(ProjectType.web)
请参阅文档:http://apidock.com/rails/ActiveRecord/SpawnMethods/merge
在最后的改进中,您可以创建一个范围:
class Portfolio
has_many :project_types
scope :web, -> { joins(:project_types).merge(ProjectType.web) }
end
并致电
Portfolio.web