我有一个联接表,用于联接Client和Setor(复数:setores)模型。关系是,一个客户有多个Setores(三个Setore,一个Client可以拥有一个到所有三个Setore。Setore有很多Client)。

我的问题是:
在此联接表中,我添加了对User模型的引用。 Setore有许多用户,但是一个客户和一个Setor之间的关系只有一个用户。但是我不知道如何在clients_setores表上读写这种关联。

我的模型如下:

class Client < ActiveRecord::Base
has_and_belongs_to_many :documents
has_and_belongs_to_many :setores
has_many :screenings
has_many :contacts
has_many :interactions, through: :contacts
validates :cnpj, uniqueness: true


class Setor < ActiveRecord::Base
  self.table_name = 'setores'
  has_many :documents
  has_many :screenings
  has_many :users
  has_and_belongs_to_many :clients
  attr_acessor :user_id


class User < ActiveRecord::Base
has_one :setores
has_many :clients


当前正在使用的连接表参数在Clients控制器的末尾显示如下:

  private
# Use callbacks to share common setup or constraints between actions.
def set_client
  @client = Client.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def client_params
  params.require(:client).permit(:cnpj, :pacote, :razsoc, :vencimento, user_ids:[], document_ids:[], setor_ids:[])
end


请注意,“ user_ids:[]”是我尝试使其正常运行,但迄今为止失败。

在视图中,我使用这样的当前联接表(摘自/client/_form.html.erb):

<%= f.collection_check_boxes :setor_ids, Setor.where(pacote: true), :id, :setor do |b| %>


因此,通过这些复选框,我可以在clients_setores表中创建一个条目。

我要做的是能够从下拉菜单中选择属于给定setor_id的用户,并将此关系存储在联接表中。我确实设法在相同的_form.html.erb中用以下代码显示了该菜单:

<%= f.collection_select :user_ids, User.where(:setor_id => 1), :id, :email %>


但是,当我提交表单时,值不会保存。我不知道我的问题是否仅仅是我没有正确的方式来记录我的观点,或者我的问题是否在控制器(可能)和模型(可能)中更深层。

我在SO中发现的最接近的问题是Rails 4 Accessing Join Table Attributes,但是关联类型不同(has_many / through),并且没有涉及第三种关系,所以我不知道如何使它对我有用。

最佳答案

使用单个连接表完成的三个模型之间的多对多关联示例:

我首先生成一些模型:

rails g model User; rails g model Setor; rails g model Client;
rails g model Joiner user_id:integer setor_id:integer client_id:integer


顺便说一句,references是一种添加引用现有模型的外键的方法。即user:references将创建一个user_id列。它还向外键添加了“索引”,从而提高了性能。

然后我向类添加一些关联

class Joiner
  # columns: user_id, setor_id, client_id
  belongs_to :user
  belongs_to :setor
  belongs_to :client
end

class User
  has_many :joiners
  has_many :setors, through: :joiners, source: :setor
  has_many :clients, through: :joiners, source: :client
end

class Setor
  has_many :joiners
  has_many :users, through: :joiners, source: :user
  has_many :clients, through: :joiners, source: :client
end

class Client
  has_many :joiners
  has_many :users, through: :joiners, source: :user
  has_many :setors, through: :joiners, source: :setor
end


编写此代码后,您将拥有这三个模型的多对多关联。

然后,您可以编写:

User.create; Setor.create;
Joiner.create(user_id: User.first.id, setor_id: Setor.first.id);
User.first.setors.length # => 1


顺便说一下,这不适用于自我联接(即嵌套评论系统),但这不是问题的一部分。

关于mysql - 连接表上的其他外键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36295753/

10-13 04:52