关于RoR数据库模式和关联的建议

时间:2012-05-26 06:59:56

标签: ruby-on-rails activerecord database-schema

RoR的新手,但我正在构建一个应用程序 - 我正在寻找关于我的数据库结构的一些建议。

我有4个型号/表:用户>客户>工作>任务

该应用程序将按如下方式运行:

  1. 用户将登录
  2. 他们可以添加客户端
  3. 他们可以向客户添加职位
  4. 他们可以向工作添加任务
  5. 因此,任务属于Jobs,Jobs属于客户端,而客户端属于Users。

    我想在DB中查询客户端,作业或任务中的任何一个,并确保它属于当前登录的用户。我正在努力编写一个'railsy'连接查询并设计我的关联,所以我可以这样做。

    我知道如果我在每个表中都有一个user_id字段,这将非常简单,但这似乎不是正确的方法。

    我在http://guides.rubyonrails.org/association_basics.html阅读了指南,但我仍然处于黑暗中。任何人都可以阐明我如何构建我的数据库 - 更重要的是我的协会?

    THX。

2 个答案:

答案 0 :(得分:2)

您似乎从一侧设置了关联,所有您需要做的就是使用has_many添加关联的另一端:

class Task < ActiveRecord::Base
  belongs_to :job
end

class Job < ActiveRecord::Base
  belongs_to :client
  has_many :tasks
end

class Client < ActiveRecord::Base
  belongs_to :user
  has_many :jobs
  has_many :tasks, :through => :jobs
end

class User < ActiveRecord::Base
  has_many :clients
  has_many :jobs, :through => :clients
  has_many :tasks, :through => :jobs
end

现在ActiveRecord将为您处理联接。确实,在纯数据库模式中,您不应该将user_id放在多个位置(这里是clients表)。但是有时它会被添加到tasks和jobs表中以提高性能,因为那时db查询不会那么大。然而,您必须付出更多努力来使数据保持一致 - 例如,您必须确保作业与其客户端具有相同的user_id。

然后您就可以定义快捷键关联,如:

class Task < ActiveRecord::Base
  belongs_to :user
end

但是在这种情况下我不会这样做,除非你发现查询对你的需求来说太慢了。过早优化是邪恶的: - )

答案 1 :(得分:1)

我不确定,如果我理解你的问题,但我相信这可以解决问题:

如果您编写这样的关联,ActiveRecord会在您要求user.jobsuser.tasks时自动创建联接。

class User < ActiveRecord::Base
  has_many :clients
  has_many :jobs, :through => :clients
  has_many :tasks, :through => :jobs
end

有关详细信息,请参阅Rails-Api-Documentation

如果您想在一个请求中获取用户的所有内容。你可以这样做:

user.clients.joins(:jobs => :tasks)