Ruby on rails Rails有许多相同的模型,但不同的实例
我正在构建一个训练跟踪应用程序。目前,我的模型设置为。。。 一个用户有许多时间表 时间表上有很多锻炼 锻炼有很多锻炼 一个练习有许多回路(包括重复/设置/重量) 一切正常 但现在我正在添加一个新的关系,我不知道如何建立。 我想有一个新的模式,一个用户有许多“已完成的训练”,其中包含了训练模式的所有属性 我的第一个想法是添加一个用户锻炼模型;为用户和训练使用外键。但这意味着每当我在训练中做出改变时,它也会反映在user.workouts中;这不是我想要的 schema.rb user.rbRuby on rails Rails有许多相同的模型,但不同的实例,ruby-on-rails,foreign-keys,relational-database,Ruby On Rails,Foreign Keys,Relational Database,我正在构建一个训练跟踪应用程序。目前,我的模型设置为。。。 一个用户有许多时间表 时间表上有很多锻炼 锻炼有很多锻炼 一个练习有许多回路(包括重复/设置/重量) 一切正常 但现在我正在添加一个新的关系,我不知道如何建立。 我想有一个新的模式,一个用户有许多“已完成的训练”,其中包含了训练模式的所有属性 我的第一个想法是添加一个用户锻炼模型;为用户和训练使用外键。但这意味着每当我在训练中做出改变时,它也会反映在user.workouts中;这不是我想要的 schema.rb user.rb cla
class用户
附表1.rb
课程表
workout.rb
课堂训练
我可以想到两种可能的解决方案,都需要一定程度的数据冗余
解决方案1:添加存储训练表时间点副本的用户\u训练模型
在这种方法中,您可以按计划添加user\u锻炼
模型,但您可以将所需的属性复制到user\u锻炼
模型,而不是仅保留对锻炼
的引用。这意味着当您的锻炼
值以后发生变化时,您的用户锻炼
将继续反映用户进行的锻炼的价值
表结构:
训练
,都需要将它们添加到用户训练
user\u-workout
中使用名为worker\u-snapshot
的散列字段,而不是所有列。这将克服第二个缺点
解决方案2:每当对“训练表”进行编辑时,都要在“训练表”中创建一个新条目
此方法假设训练只能有固定值,如果训练中有任何变化,则表示正在创建新的训练。这意味着不需要对训练进行“更新”,只要在需要更新的情况下,使用修改后的旧训练值创建新训练即可。然后,用户锻炼
表可以直接指向锻炼id,而无需担心锻炼数据的变化
优点:
user\u锻炼
表来担心锻炼的更改
workout\u快照的第一种方法
注意:我建议取消数据库结构的规范化。您的两个表只有name
列,并以多对多关系链接到其他表。我建议改变一些事情:
您可以在user\u schedules
本身中有一个name
字段,并删除schedules
表。用户计划本身可以有各种练习
一个练习可以有一个名称和一个workout\u id
,并且可以删除workout\u exercises
表
我认为这些建议可能有助于降低数据库结构的复杂性。我知道我对你正在建设的东西有一个非常有限的想法,这个建议可能是非常无用的,在这种情况下,你可以忽略它 感谢您对表格更改的建议。我认为对于我的用例来说,第一个aproach更有意义。如果我使用第一种解决方案,用户的训练模型是否与训练模型文件相同?是否具有相同的关联?是的,如果不使用快照散列,则会。但是,正如我所说,如果只是为了显示内容或跟踪,我强烈建议只使用一个散列来保存快照。在用户训练
模型上维护关联的缺点是,如果训练或他们的关系发生变化,它们可能会成为维护的噩梦。例如,与练习关联的回路发生变化时会发生什么情况?在这种情况下,用户\u训练
也将开始指向新回路。这就是为什么我更喜欢解决方案1+快照散列,或者将解决方案2替换为没有散列的解决方案1可能会导致可维护性问题。
create_table "circuits", force: :cascade do |t|
t.integer "weight"
t.integer "reps"
t.integer "rest"
t.integer "exercise_id"
end
create_table "exercises", force: :cascade do |t|
t.string "name"
end
create_table "schedules", force: :cascade do |t|
t.string "name"
end
create_table "user_schedules", force: :cascade do |t|
t.integer "user_id"
t.integer "schedule_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "username"
end
create_table "workout_exercises", force: :cascade do |t|
t.integer "workout_id"
t.integer "exercise_id"
end
create_table "workout_schedules", force: :cascade do |t|
t.integer "workout_id"
t.integer "schedule_id"
end
create_table "workouts", force: :cascade do |t|
t.string "name"
end
class User < ApplicationRecord
has_many :user_schedules
has_many :schedules, through: :user_schedules
end
class Schedule < ApplicationRecord
has_many :user_schedules
has_many :users, through: :user_schedules
has_many :workout_schedules
has_many :workouts,through: :workout_schedules
accepts_nested_attributes_for :workouts
end
class Workout < ApplicationRecord
has_many :workout_exercises
has_many :exercises,through: :workout_exercises
has_many :workout_schedules
has_many :schedules,through: :workout_schedules
end