Helban Helban - 1 year ago 55
MySQL Question

RoR: if a company exists, assign company_id to user, otherwise create the company

I want to modify my application in a way that on the signup page, user specifies his company. If the company with a particular name already exists, the newly created user gets assigned to the company (by company_id), if not, the company gets created in the company table, and the user gets the company_id assigned in the users table record.

I've managed to make the app create the user, and create a correct company in another table, But I can't figure out how to make it so that if the company already exists, user just gets the existing company id.

Now on to what I've done so far. One user belongs to one company, and one company has many users.

The user table has a new column named company_id

The Company table has company_name

As for models:

User Model (... truncates unnecesary code)

class User < ActiveRecord::Base
belongs_to :company
accepts_nested_attributes_for :company

Company model:

class Company < ActiveRecord::Base
validates :company_name, presence: true, length: { maximum: 140}
has_many :employees, class_name: "User",
dependent: :destroy


As for Controllers:

The users controller create method looks like this:

def create
@user = User.new(user_params)
if @user.save
flash[:info] = I18n.t("controllers.users_controller.check_email")
redirect_to root_url
render 'new'

When user_params are:

def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation, company_attributes:[:company_name])

The companies controller is empty..

And the form for submitting is constructed like this:

<% @user.build_company %>
<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages', object: f.object %>

<%= f.label I18n.t("users.form.name") %>
<%= f.text_field :name, class: 'form-control' %>

<%= f.label I18n.t("users.form.email") %>
<%= f.email_field :email, class: 'form-control' %>

<%= f.fields_for :company do |builder| %>
<%= builder.label I18n.t("users.form.company_name") %>
<%= builder.text_field :company_name, :class => "form-control" %>

<%= f.label I18n.t("users.form.password") %>
<%= f.password_field :password, class: 'form-control' %>

<%= f.label I18n.t("users.form.password_confirmation") %>
<%= f.password_field :password_confirmation, class: 'form-control' %>

<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>

I think that is all the information necessary I can think of, If you need anything else, please tell me.

Now I hit a brick wall, and not really sure how to move on from this place. Where and How should I implement something that checks if the input company name already exists, and if it does, give the users' column company_id the existing company id from the companies table, and otherwise just create the company and get him the new id.

Also, on a side note, did I understood good that the dependent: :destroy at company model will cause that if I delete a company from the database, all the users that belonged to the company will also be deleted?(at least that's what I wanted to achieve).

I will appreciate all the help!

Best regards,

Answer Source

Add :autosave. With this you can then use autosave_associated_records_for_company to determine how to save the child when parent is saved.

class User < ActiveRecord::Base
  belongs_to :company, autosave: true
  accepts_nested_attributes_for :company

  def autosave_associated_records_for_company
    if company  
      # Find or create the company by name
      if new_company = Company.find_by_company_name(company.company_name)
        self.company = new_company
        self.company_id = self.company.id
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download