通过 has_many 的 Rails 4 应用程序

Posted

技术标签:

【中文标题】通过 has_many 的 Rails 4 应用程序【英文标题】:Rails 4 app with has_many through 【发布时间】:2015-04-08 04:15:29 【问题描述】:

我需要制作一个有两种模型的应用程序:用户和公司。在这种情况下,用户可能是公司的员工,那么用户必须与公司模型关联,如果用户不是公司的员工,则不应与公司模型关联。

我正在尝试通过关联 has_many 来实现:

型号:

# == Schema Information
#
# Table name: companies
#
#  id         :integer          not null, primary key
#  name       :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Company < ActiveRecord::Base

  has_many :company_users
  has_many :users, through: :company_users
end

# == Schema Information
#
# Table name: users
#
#  id              :integer          not null, primary key
#  first_name      :string
#  last_name       :string
#  email           :string
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#

class User < ActiveRecord::Base

  has_many :company_users
  has_many :companies, through: :company_users
end

# == Schema Information
#
# Table name: company_users
#
#  id         :integer          not null, primary key
#  company_id :integer
#  user_id    :integer
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class CompanyUser < ActiveRecord::Base

  belongs_to :company
  belongs_to :user
end

公司控制人

class CompaniesController < ApplicationController

  def signup
    @company = Company.new
    @user = @company.users.build
  end

  def create
    @company = Company.new(company_params)
    @company.save
  end

  private

  def company_params
    params.require(:company).permit(:name, users_attributes: [:first_name, :last_name, :email])
  end
end

signup.html.erb

<%= form_for(@company) do |f| %>
  <%= f.text_field :name %>         
  <%= f.fields_for(@user) do |user_f| %>
    <%= user_f.text_field :first_name %>
    <%= user_f.text_field :last_name %>
  <% end %>
  <%= f.submit %>
<% end %>

但它不起作用。仅保存了公司模型的实例。 必须如何在模型中进行关联,以及在控制器操作中应该如何进行公司与员工创建公司?

【问题讨论】:

【参考方案1】:

除非有一些特定于公司和用户之间关系的额外信息,否则我会改用 has_and_belongs_to_many 关系,并在您的应用中少一个模型。

在这种情况下,您的类将如下所示:

class Company < ActiveRecord::Base
  has_and_belongs_to_many :users
  accepts_nested_attributes_for :users
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :companies
end

Company 中的第二行是您缺少的内容,它告诉 Rails 留意 users_attributes

有关嵌套属性的更多详细信息:

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

如果你想保留关系模型,那么我相信你需要嵌套你的嵌套属性,例如

class Company < ActiveRecord::Base
  has_and_belongs_to_many :company_users
  accepts_nested_attributes_for :company_users
end

class CompanyUser < ActiveRecord::Base
  belongs_to :company
  belongs_to :user

  accepts_nested_attributes_for :user
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :company_users
end

您的表单数据需要如下所示:

company[company_users][][user][first_name]=First

【讨论】:

是的,但我需要将关系模型作为一个独立的实体使用。 在这种情况下,我相信您需要嵌套嵌套属性。我用一个例子更新了我的答案

以上是关于通过 has_many 的 Rails 4 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Has_many:通过 Rails 4 实例变量不起作用

Rails 4找不到关联has_many,通过:关系错误

如何使用带有 has_many 的 PaperTrail 版本控制:通过在 Rails 4 中实现关联

Rails 4找不到关联has_many,通过:关系错误

Rails:has_many 通过关联 - 我做对了吗?

Rails 成语避免在 has_many 中重复:通过