我正在构建一个Ruby on Rails 4.1应用程序,它具有以下模型,当您看到模型名称时应该有意义:
域名,团队,用户,会议等
现在,团队属于一个域,一个用户属于一个团队,会议也属于一个用户。域只是使用该软件的组织或公司。
创建管理员用户后,用户必须首先创建域,然后创建第一个团队,然后其他用户就可以注册。
正如您可能预料到的那样,在创建初始域和团队(在新的/创建团队和域控制器中完成)的过程中,我必须访问和更改所有三个中的引用。因此,例如,创建第一个域必须关联管理员用户,创建一个团队将涉及将其链接到用户,然后是父域。
所以,它们有点混乱,控制器需要访问多个模型。
我的问题是,这个逻辑属于哪里?根据瘦控制器的精神,您通常会将其移植到模型中,但它涉及多个模型。这是新的Rails 4问题变得有用还是我应该把它放在控制器中?
我对铁杆比较陌生,所以如果你愿意回复,请记住这一点 - 谢谢!
答案 0 :(得分:3)
class Domain
has_many :teams
end
class Team
has_many :users
belongs_to :domain
end
class User
has_many :meetings
belongs_to :team
end
class Meeting
belongs_to :user
end
然后在你的控制器中:
class TeamsController < ApplicationController
def new
@team = Team.new
end
def create
@domain = Domain.find(params[:domain_id])
@team = @domain.teams.build(params[:team])
@team.save
respond_with @team
end
end
这就是我们所谓的“嵌套”控制器,位于routes.rb
文件中:
resources :domain do
resources :team
end
网址将如下所示:
/domains/:domain_id/teams
/domains/:domain_id/teams/:team_id
同样的逻辑适用于其他型号。这应该为您提供构建应用程序的起点。
以下一行
@domain.teams.build(params[:team])
自动将域链接到为您设置引用(id
)的团队。
但是你不应该根据rails guide进行深度嵌套,这样建筑师设计模式可以派上用场。
然而,如果事情开始变得混乱,我建议使用专用的ruby类来“构建”你的对象及其关系。我们通常将这些类称为“构建器”:
class TeamBuilder
attr_reader :domain, :params
def initialize(domain, params = {})
@domain = domain
@params = params
end
def build
domain.teams.build(params)
end
end
这里又做了一个非常简单的任务。例如,对于用户和会议:
class UserBuilder
attr_reader :team, :params
def initialize(team, params = {})
@team = team
@params = params
end
def build
team.users.build(params).tap do |user|
user.foo = 'foo'
user.meetings.build(...)
user.meetings << MeetingBuilder.new(user, { ... })
end
end
end
class MeetingBuilder
# ...
end
我们使用MeetingBuilder
中的UserBuilder
来构建会议。
用法:
user = UserBuilder.new(team, { ... }).build
user.save
答案 1 :(得分:1)
理想情况下,模型不应该关心甚至不了解其他类。因此在模型和控制器之间,这种逻辑肯定属于控制器。
我可能会选择第三课,照顾那些混乱的东西,例如DomainFactory。这只是一个普通的旧红宝石对象(poro),没有活动记录或任何东西,其唯一目的是创建域名。
提示是阅读松散耦合和单一责任。