I'm building a time tracker. You can create a timestamp with a start time, end time, customer and a project from this customer. So you can see how much time you've spent for a project or customer.
The relationships between tables with "has_many" works perfectly but I have a problem with the "has_one" relation.
My tables:
timestamps customers projects
---------- ------------ -----------
id:integer id:integer id:integer
desc:string customer_name:string project_name:string
customer_id:interger project_id:integer
My models:
timestamp.rb
class Timestamp < ActiveRecord::Base
has_one :customer
has_one :project, through: :customer
end
customer.rb
class Customer < ActiveRecord::Base
belongs_to :timestamp
has_many :projects, dependent: :destroy
end
project.rb
class Project < ActiveRecord::Base
belongs_to :customer
end
My goals:
Timestamp.create({desc: "Something", customer_id: "1", project_id: "6"})
Timestamp.find(1).customer.project
My problem:
I can make this work if I include a timestamp_id into the projects table but with this method, Rails duplicates every project with the specific timestamp_id when I'm creating a new timestamp. But I want to assign one project_id to the timestamp.
FYI: I'm using rails 4.2.6 with a MYSQL Database.
Because you do not want to have duplicate projects and duplicate customers per timestamp, then you'd need to set only foreign keys to the timestamp. By that you would want to have tables with the following columns:
Timestamps
customer_id:integer:index
project_id:integer:index
Customers
Projects
customer_id:integer:index
You'll have to write and run migrations to remove columns, and add columns so that it will look above.
Then, modify associations:
class Timestamp < ActiveRecord::Base
belongs_to :customer # change to belongs_to
has_many :projects, through: :customer # you might not need this anymore because of the line below
belongs_to :project # add this line
end
class Customer < ActiveRecord::Base
has_one :timestamp # change to has_one
has_many :projects, dependent: :destroy
end
class Project < ActiveRecord::Base
belongs_to :customer
has_one :timestamp # add this line
end
Then, you could now use the following
Timestamp.find(1).customer
Timestamp.find(1).project
Timestamp.find(1).projects # these projects are customer.projects and are not directly associated to the line above, so I don't think you would need to call this