-
Notifications
You must be signed in to change notification settings - Fork 0
3.1. Companies Model
The idea of this section is to learn how to create a new model and add basic attributes and validations.
First of all, we are going to create a new model Company with the following attributes:
- id: integer
- name: string
- entity: enum(llc, c_corp, s_corp)
- phone: integer
- user_id: integerRails provides an easy way to do this by running this command:
foo@bar:~$ rails generate model Company user:references name:string entity:integer phone:integer
invoke active_record
create db/migrate/20220818153944_create_companies.rb
create app/models/company.rb
invoke test_unit
create test/models/company_test.rb
create test/fixtures/companies.ymlYou can notice that we didn't specify the id attribute. That's because it's handled by Rails behind scenes, so you never have to specify that.
You can also see that for the enum attribute, we indicated it to be an integer, and that's for performance purposes as it's faster to use integers than strings. We will specify the options in a moment.
If you check the file db/migrate/20220818153944_create_companies.rb you should have something like this:
class CreateCompanies < ActiveRecord::Migration[7.0]
def change
create_table :companies do |t|
t.references :user, null: false, foreign_key: true
t.string :name
t.integer :entity
t.integer :phone
t.timestamps
end
end
endThat's how a migration in Rails looks like. Have in mind that table names are always pluralized.
If you don't know yet what attributes the migration is going to contain, you can omit them when running the command.
Lastly, t.timestamps adds created_at and updated_at to our model.
Let's now execute the migration by running this:
foo@bar:~$ rails db:migrateIf you check the file app/models/company.rb, you should have this:
class Company < ApplicationRecord
belongs_to :user
endNow we are going to add the enum values as follows:
class Company < ApplicationRecord
enum entity: { llc: 0, c_corp: 1, s_corp: 2 }
endAs you saw we added user:references when generating the model. That adds a foreign key in the companies table pointing to the users table. We will now tell Rails we have a relationship there.
To do that, we can use the keyword belongs_to in the Company side.
class Company < ApplicationRecord
enum entity: { llc: 0, c_corp: 1, s_corp: 2 }
belongs_to :user
end... and has_one on the User side.
class User < ApplicationRecord
...
has_one :company, dependent: :destroy
...
endWith dependent: :destroy we tell Rails to destroy the company record if the user gets destroyed.
We want now to avoid Companies with empty and repeated names. To solve that, Rails introduces validations that can be added in the following way. For further reading check out the link.
class Company < ApplicationRecord
enum entity: { llc: 0, c_corp: 1, s_corp: 2 }
belongs_to :user
validates :name, presence: true, uniqueness: true
endThe integers 0, 1 and 2 are the values that will be stored in the database.
We are looking better now, but that's not enough. We are covered on the Rails side, but not database-wise, as the table companies allows empty and repeated names. Let's fix it.
We will create a new migration to add a unique index and set the nullable condition.
foo@bar:~$ rails generate migration AddNameIndexToCompaniesYou should have now a new file in the db/migrate folder that we will edit to introduce the index. We will have this:
class AddNameIndexToCompanies < ActiveRecord::Migration[7.0]
def change
change_column :companies, :name, :string, null: false
add_index :companies, :name, unique: true
end
endRun the migration and you are good to go.
foo@bar:~$ rails db:migrate