Reputation: 721
I can't solve my problem for already a week.
I have 4 models: Person, Position, Workspace, and Phonenumber.
The hierarchy is Person > Position > Workspace > Phonenumber.
A chain of all 4 models is unique. Say, there may be only one man:
Person | Position | Workspace | Phonenumber |
Smith Engineer Department #4 555-666
But there may be another man with the same Position, Workspace, and Phonenumber:
Person | Position | Workspace | Phonenumber |
Johnson Engineer Department #4 555-666
Or even the same Mr. Smith, but different position or workspace.
Person | Position | Workspace | Phonenumber |
Smith Engineer Department #7 555-666
And so on.
All 4 at the same time are unique.
I want to store this data. I tried many different things. Nothing helped me at 100%. For now my best idea is to use has_many through relationships with join model called Employee:
person_id | position_id | workspace_id | phonenumber_id
But how do I work with data?
Say, I want to create new person with some position, workspace and phonenumber. How do I do that?
Upvotes: 1
Views: 815
Reputation: 8318
To create your setup in a Rails 4 application:
rails g model Person last_name
rails g model Position job_title
rails g model Workspace name
rails g model Phonenumber number
rails g model Employee person_id:integer position_id:integer workspace_id:integer phonenumber_id:integer
app/models/person.rb
class Person < ActiveRecord::Base
has_many :employees, :dependent => :destroy
has_many :positions, :through => :employees
has_many :workspaces, :through => :employees
has_many :phonenumbers, :through => :employees
validates :last_name,
:presence => true
end
app/models/employee.rb
class Employee < ActiveRecord::Base
belongs_to :person
belongs_to :position
belongs_to :workspace
belongs_to :phonenumber
validates :person, :position, :workspace, :phonenumber,
:presence => true
validates :person_id,
:presence => true,
:uniqueness => { :scope => [ :position_id, :workspace_id, :phonenumber_id ]}
end
Now to create a new Person
with everything:
Person.create(:last_name => 'Smith').employees.where(:position => Position.where(:job_title => 'Engineer').first_or_create, :workspace => Workspace.where(:name => 'Department #8').first_or_create, :phonenumber => Phonenumber.where(:number => '555-666').first_or_create).first_or_create
To create an other Position
for this Smith:
Person.where(:last_name => 'Smith').last.employees.where(:position => Position.where(:job_title => 'Admin').first_or_create, :workspace => Workspace.where(:name => 'Department #8').first_or_create, :phonenumber => Phonenumber.where(:number => '555-667').first_or_create).first_or_create
first_or_create
searches for the entry or creates a new one.
Upvotes: 1