Ruby on rails Rails关系(有多个/属于)已完成
所以我已经有相当长的一段时间没有处理人际关系了,我想确保我做得对 在我的客户模型中,我有:Ruby on rails Rails关系(有多个/属于)已完成,ruby-on-rails,Ruby On Rails,所以我已经有相当长的一段时间没有处理人际关系了,我想确保我做得对 在我的客户模型中,我有: class Client < ApplicationRecord has_many :projects, dependent: :destroy end 类客户端
class Client < ApplicationRecord
has_many :projects, dependent: :destroy
end
类客户端
在我的项目模型中,我有:
class Project < ApplicationRecord
belongs_to :client
end
类项目
所以我知道一切都安排好了。然后,为了抓取我放在项目控制器中的项目:
def create
@client = Client.find(params[:client_id])
@project = @client.project.new(project_params)
flash[:notice] = "Project created successfully" if @client.project << @project
respond with @project, location: admin_project_path
end
def创建
@client=client.find(参数[:client\u id])
@project=@client.project.new(项目参数)
flash[:notice]=“Project created successfully”如果@client.Project我会这样想:
def create
@client = Client.find(params[:client_id])
@project = @client.project.new(project_params)
flash[:notice] = "Project created successfully" if @client.project << @project
respond with @project, location: admin_project_path
end
注意
@project = @client.project.new(project_params)
应该是:
@project = @client.projects.new(project_params)
正如Yechiel K所说,没有必要这样做:
@client.project << @project
将在新的@项目上自动设置客户端id
。顺便说一句,如果您想手动将项目
添加到客户端
,那么它是:
@client.projects << @project
而且,用
回应也不是什么事<代码>用
回应是一件事。(我相信它已经转移到一个单独的gem,响应者
)您的代码不清楚您是否需要不同的响应,例如,对于html
和js
。如果不是的话,我想这更像是:
def create
if @client = Client.find_by(id: params[:client_id])
@project = @client.projects.new(project_params)
if @project.save
flash[:notice] = "Project created successfully"
redirect_to [@client, @project]
else
# do failure stuff
end
else
# do something when client not found
end
end
这假设您的路线看起来像:
Rails.application.routes.draw do
resources :clients do
resources :projects
end
end
在这种情况下,rails将把[@client,@project]
解析为正确的路由/路径
正如DaveMongose所提到的,您可以将@client=client.find_by(id:params[:client_id])
移动到操作之前的。这是很常见的。关于为什么不这样做的一个讨论。就我个人而言,我过去常常在行动前使用,
,但现在不再使用了。作为替代方案,您可以执行以下操作:
class ProjectsController < ApplicationController
...
def create
if client
@project = client.projects.new(project_params)
if @project.save
flash[:notice] = "Project created successfully"
redirect_to [client, @project]
else
# do failure stuff
end
else
# do something when client not found
end
end
private
def client
@client ||= Client.find_by(id: params[:client_id])
end
end
class ProjectsController < ApplicationController
...
def create
if client
if new_project.save
flash[:notice] = "Project created successfully"
redirect_to [client, new_project]
else
# do failure stuff
end
else
# do something when client not found
end
end
private
def client
@client ||= Client.find_by(id: params[:client_id])
end
def new_project
@new_project ||= client.projects.new(project_params)
end
end
class ProjectsController
再进一步,您可以执行以下操作:
class ProjectsController < ApplicationController
...
def create
if client
@project = client.projects.new(project_params)
if @project.save
flash[:notice] = "Project created successfully"
redirect_to [client, @project]
else
# do failure stuff
end
else
# do something when client not found
end
end
private
def client
@client ||= Client.find_by(id: params[:client_id])
end
end
class ProjectsController < ApplicationController
...
def create
if client
if new_project.save
flash[:notice] = "Project created successfully"
redirect_to [client, new_project]
else
# do failure stuff
end
else
# do something when client not found
end
end
private
def client
@client ||= Client.find_by(id: params[:client_id])
end
def new_project
@new_project ||= client.projects.new(project_params)
end
end
class ProjectsController
我将替换这一行:
flash[:notice] = "Project created successfully" if @client.project << @project
无需手动将@project
添加到@client.projects
,当您使用@client.projects.new
创建它时,它会自动添加。您唯一错过的是,使用.new
创建某些内容不会将其保存在数据库中,这可以通过调用@project.save
来完成
对于您的显示操作,我不确定您指的是客户端的显示页面还是项目的显示页面,但在这两种情况下,您都可以使用params[:id]
(除非您使用一些嵌套路由)。只需检查,但在模型中,它实际上属于:client
,并且有许多带有冒号的:projects
?在您看来,有几种方法可以做到这一点,但是@client.projects
将包含客户端的项目,以便循环@client.projects。每个do | proj |
等都将循环通过该客户端项目。这就是你要问的吗?修复了丢失的冒号。是的,我只是想确保我可以轻松访问客户的项目。以下内容对你有用吗?非常全面的答案!另一件可能值得一提的事情是,如果其他操作(如show)也是特定于客户端的,则将@client=…
行移动到之前的操作中。我可能会在某些时候使用友好id来传递参数。
flash[:notice] = "Project created successfully" if @client.project << @project
flash[:notice] = "Project created successfully" if @project.save