首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rails应用程序的最优表关系

rails应用程序的最优表关系
EN

Stack Overflow用户
提问于 2014-08-04 08:35:33
回答 2查看 48关注 0票数 0

让我们假设,我想编写一个应用程序,允许用户根据不同的标准搜索汽车。例如,用户首先知道哪种模型是从特定的汽车制造中建立的;或者,根据汽车制造和模型过滤汽车。

为了达到这个目的,我开始设计我在Db中需要的所有表:

  • 制造业
  • 模型
  • 汽车

Idea A

每一种车型都与一家汽车制造商相关联,而一辆汽车只能与一种车型相关联。

Advantage这种结构可以让我轻松地识别属于某一特定汽车制造商的所有车型或属于特定车型的所有汽车。

Disadvantages进入汽车表,没有直接显示汽车制造的迹象(仅通过汽车型号)。

Idea B

每一辆车都与汽车制造和型号有关。

Advantage,我现在可以访问汽车的所有信息,而无需浏览其他表。

Disadvantages如果我想找到所有与特定型号或制造相关的汽车,任务看起来很复杂。

我的问题

  1. 哪一种是最好的策略?有没有更好的解决办法?
  2. 哪一个是从收集数据的角度来看,更快?
EN

回答 2

Stack Overflow用户

发布于 2014-08-04 09:04:45

我会坚持你的版本A,因为它更准确地反映了你正在建模的数据。每个型号只由一个制造商制造,如果你知道汽车的型号,你可以立即推断出制造商。在B版中,没有这样的链接。

就Rails内部的关联而言,您可以很容易地对这些关系建模:

代码语言:javascript
复制
class Manufacturer < ActiveRecord::Base
  has_many :models
  has_many :cars, through: :models
end

class Model < ActiveRecord::Base
  belongs_to :manufacturer
  has_many :cars
end

class Car < ActiveRecord::Base
  belongs_to :model
end

就直接访问汽车制造商而言,@car.model.manufacturer当然可以工作,但您也可以使用委托方法来更直接一些:

代码语言:javascript
复制
class Car < ActiveRecord::Base
  belongs_to :model
  delegate :manufacturer, to: :model
end

当涉及到搜索时,Rails会让你到达你需要去的地方。例如,要找到所有的汽车制造商,名为“福特”:

代码语言:javascript
复制
Car.joins(:model => :manufacturer).where(manufacturers: { name: 'Ford' })

如果需要执行更复杂的查询,可以在joinswhere调用中包含相关的SQL片段。如果您超出了ActiveRecord的DB调用和作用域链接,您可以探索像尖叫声这样的扩展,或者直接访问阿雷尔 --但是您描述的项目应该可以处理AR的本机调用,至少在开始时是这样的。

在“收集数据”方面--您的方法B将使您能够使用Rails助手构建一个表单,该表单能够将两个关联转换为下拉列表或单选按钮。然而,正如我上面所说的,您将失去数据建模的准确性。考虑一下添加/删除制造商和模型的频率--如果它们经常更新,这将对您的用户界面产生很大影响,而不是所有制造商和模型都是预先定义的,很少更改。

票数 0
EN

Stack Overflow用户

发布于 2014-08-04 10:40:49

这样做:

代码语言:javascript
复制
#app/models/car.rb
Class Car < ActiveRecord::Base
   #fields id | manufacturer_id | name | model | other | information | created_at | updated_at
   belongs_to :manufacturer
end

#app/models/manufacturer.rb
Class Manufacturer < ActiveRecord::Base
   #fields id | name | foundation_year | etc | etc
   has_many :cars
end

#app/models/model.rb
Class Model < Car
   self.inheritance_column = :model # http://apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/inheritance_column
   #this uses the Car model to populate different "models". It will allow you to identify the model based on the car - using the same table for all
end

对于Model,您可能不需要单独的表,因为我假设Car本身就是一个Model?相反,我会考虑使用STI (单表继承)根据您定义的模型调用任何特定的汽车模型:

代码语言:javascript
复制
#app/controllers/models_controller.rb
Class ModelsController < ApplicationController
   def show
       @cars = Model.find params[:id]
   end
end

您确实应该使用多个模型的STI (IE为您的汽车的每个Model都有一个特定的模型)。我建议反对的原因是因为我假设您的每个Car对象都有自己的模型。

如果情况并非如此,请使用下面的建议。然而,

多模型

处理模型/汽车的一个更简单的方法是为模型使用一个简单的关联:

代码语言:javascript
复制
#app/models/car.rb
Class Car < ActiveRecord::Base
   # fields id | manufacturer_id | name | other | car | details | created_at | updated_at
   has_many :models
   belongs_to :manufacturer
end

#app/models/manufacturer.rb
Class Manufacturer < ActiveRecord::Base
   has_many :cars
   #fields id | name | foundation_year | other | attributes | created_at | updated_at
end

#app/models/model.rb
Class Model < ActiveRecord::Base
   #fields id | name | wheels | engine | etc | created_at | updated_at
   belongs_to :car
end

这让你能够创造不同的车型每辆“车”- IE有一个“运动”版本等。

ActiveRecord

你将是最好的阅读ActiveRecord关联,他们在Rails中扮演的角色

您必须考虑Rails以 objects为中心,这意味着您所做的一切都必须尽可能地模块化。如果同一个对象有一个具有多个属性的表,就会遇到问题

您需要考虑对象之间的关系(关联),到您需要构造模型以反映它们将如何被调用的程度。这一点非常重要,因为目前您正在寻找数据库设置--您需要将焦点切换到对象安装程序

理想情况下,您希望这样:

代码语言:javascript
复制
@car = Car.find params[:id]
@car.models.each do |model|
   model.name
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25114630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档