1

The following is my model structure

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

I want to create record using association and nested form and right now I am able to create Company along with user using nested form, but I also want to create user_role for User.

I have included accepts_nested_attributes_for :users in company model. and used fields_for to create user in company new form.

The following is my form

<%= 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 %>

Right now, the user_role is not created when creating the company. I'm not sure how to proceed.

Any guidance will be appreciated. Thanks in advance.

5
  • user_role is not created, so there must be some sort of error message or reason why it is not created. Include your controller code, include the output of @company.errors.full_messages and the check how your parameters are showing up. Maybe the user_role is not saving because it is not valid. user_role has a belongs_to :user and a belongs_to :role, optional: true. The validation of the presence of role will be skipped, but you need to have a valid user. If you are giving that user_role a user_id which belongs to an unsaved user, the validation will fail. Commented Sep 26, 2017 at 10:16
  • Thanks for the quick reply @Fabrizio, I have validate user . UserRole is third table for user and company. fields for user_role is user_id, role_id and company_id. It creating user_role with user_id and company_id, but not including role_id into user_role record. Please look into strong params params.require(:company).permit(:name, :website, :phone, :description, :company_image, users_attributes: [:email, :first_name, :last_name, :phone, :string, :birth_date, :join_date, :gender, :password, :password_confirmation]) Commented Sep 26, 2017 at 10:24
  • the user_role belongs_to user. user_role.user_id must correspond to the id of an existing user. The field id of a row in users. If you try to save user_role and the user has not been already saved, you will trigger a validation error and the user_role will not be saved. Save the user before creating the user_role Commented Sep 26, 2017 at 10:28
  • You structured your db wrong. user has_one :role and role has_many :users. You just set the user.role_id field when you create the user. No need to create the object, you create in your seed.rb file the standard roles and if you need you provide functionality to create the roles separately. When you create the user, you just set the role he will have, not create an object. guides.rubyonrails.org/association_basics.html Commented Sep 26, 2017 at 10:33
  • @wish check my solution. It should work for you.Its tested. Commented Sep 26, 2017 at 18:10

2 Answers 2

1

I want to create record using association and nested form and right now I am able to create Company along with user using nested form, but I also want to create user_role for User.

Before creating a user_role you need to commit and save to the db your user, otherwise you will run into a validation error.

user_role is not saved because the user_id you are setting does not correspond to a saved user

user_role belongs_to user. user_role.user_id must correspond to the id of an existing user (field id of a row in users). If you try to save user_role object and the user has not been already saved, you will trigger a validation error and the user_role will not be saved. Save the user in your controller before creating the user_role.

Sign up to request clarification or add additional context in comments.

1 Comment

You did great try but, as I told you before > It creating user_role with user_id and company_id, but not including role_id into user_role record. Problem is not with user object issue is to save complete record.
0

MODELS

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 %>

Follow this and it should work for you

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.