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