使用through association和nested_form_for rails创建记录

时间:2017-09-26 09:53:11

标签: ruby-on-rails associations ruby-on-rails-5 nested-form-for

以下是我的模型结构

role.rb 

has_many :user_roles 
has_many :users, through: :user_roles 
has_many :companies, through: :user_roles

user.rb

has_one :user_role, dependent: :destroy
has_one :role, through: :user_role
has_one :company, through: :user_role 

company.rb

has_many :user_roles, dependent: :destroy 
has_many :users, through: :user_roles
has_many :roles, through: :user_roles

user_role.rb

belongs_to :user
belongs_to :role, optional: true
belongs_to :company

我想使用关联和嵌套表单创建记录,现在我可以使用嵌套表单与用户一起创建公司,但我也想为User创建user_role。 < / strong>

我在公司模型中加入了accepts_nested_attributes_for :users。 并使用fields_for以公司新形式创建用户。

以下是我的表格

<%= form_for @company, html: { multipart: true } do |f| %>
  <% if company.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(company.errors.count, "error") %> prohibited this company from being saved:</h2>

      <ul>
      <% company.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field form-group">
    <%= f.label :name %>
    <%= f.text_field :name, class: :"form-control" %>
  </div>

  <div class="field form-group">
    <%= f.label :website %>
    <%= f.text_field :website, class: :"form-control" %>
  </div>

  <div class="field form-group">
    <%= f.label :phone %>
    <%= f.text_field :phone, class: :"form-control" %>
  </div>

  <div class="field form-group">
    <%= f.label :description %>
    <%= f.text_area :description, class: :"form-control" %>
  </div>

  <div class="field form-group">
    <%= f.file_field :company_image %>
  </div>

  <%= f.fields_for :users do |builder| %>
    <%= render "users_fields", :f => builder %>
  <% end %>

  <div class="actions">
    <%= f.submit class: :'btn btn-default' %>
  </div>

<% end %>

目前,创建公司时未创建user_role。我不知道该怎么办。

任何指导将不胜感激。提前谢谢。

2 个答案:

答案 0 :(得分:0)

  

我想使用关联和嵌套表单创建记录,现在我可以使用嵌套表单与用户一起创建公司,但我也想为用户创建user_role。

在创建user_role之前,您需要提交并保存到db user,否则您将遇到验证错误。

user_role未保存,因为您设置的user_id与保存的user

不对应

user_role belongs_to用户。 user_role.user_id必须与id中现有userid行)的users字段user_role对应。如果您尝试保存user对象并且user_role尚未保存,则会触发验证错误,并且不会保存user。在创建user_role之前,将import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { EditModalComponent } from './edit-modal/edit-modal.component'; @NgModule({ imports: [ CommonModule ], declarations: [EditModalComponent], exports: [EditModalComponent] }) export class EditModule { } 保存在控制器中。

答案 1 :(得分:0)

  

<强>模型

<强> 1.company.rb

# put inverse_of otherwise it will throw error. To know more about inverse of go throw docs
has_many :user_roles, inverse_of: :company
has_many :users, through: :user_roles
has_many :roles, through: :user_roles

accepts_nested_attributes_for :user_roles

<强> 2.user_role.rb

belongs_to :user
belongs_to :role
belongs_to :company

# user_roles_attributes will accept nested attributes for both user and role
accepts_nested_attributes_for :role
accepts_nested_attributes_for :user

<强> 3.user.rb

has_many :user_roles#, inverse_of: :user
has_many :roles, through: :user_roles
has_many :company, through: :user_roles

<强> 4.role.rb

has_many :user_roles
has_many :users, through: :user_roles
has_many :companies, through: :user_roles
  

<强> Companycontroller.rb

def new
    @company = Company.new
    urole = @company.user_roles.build
    urole.build_user
    urole.build_role
end

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

private 
def company_params
  # here put associate modal attributes to permit.
  params.require(:company).permit(:company_name,
    user_roles_attributes: [
      role_attributes: [:role_name],
      user_attributes: [:user_name, :email]
    ]
  )
end
  

<强> form.html.erb

<%= form_for @company, html: { multipart: true } do |f| %>


  <%=f.fields_for :user_roles do |user_roles_builder| %>

    --USER DETAILS--
    <br>
    <%=user_roles_builder.fields_for :user do | user_builder | %>
      <%= render "users_fields", :f => user_builder %>
    <% end %>
    <br>


    -- ROLE DETAILS--
    <br>
    <%=user_roles_builder.fields_for :role do | role_builder | %>
      <%= render "users_fields", :f => role_builder %>
    <% end %>

  <% end %>

  <div class="actions">
    <%= f.submit %>
  </div>

<% end %>

按照此操作,它应该适合您