Ruby on rails Rails有许多相同的模型,但不同的实例

Ruby on rails Rails有许多相同的模型,但不同的实例,ruby-on-rails,foreign-keys,relational-database,Ruby On Rails,Foreign Keys,Relational Database,我正在构建一个训练跟踪应用程序。目前,我的模型设置为。。。 一个用户有许多时间表 时间表上有很多锻炼 锻炼有很多锻炼 一个练习有许多回路(包括重复/设置/重量) 一切正常 但现在我正在添加一个新的关系,我不知道如何建立。 我想有一个新的模式,一个用户有许多“已完成的训练”,其中包含了训练模式的所有属性 我的第一个想法是添加一个用户锻炼模型;为用户和训练使用外键。但这意味着每当我在训练中做出改变时,它也会反映在user.workouts中;这不是我想要的 schema.rb user.rb cla

我正在构建一个训练跟踪应用程序。目前,我的模型设置为。。。 一个用户有许多时间表 时间表上有很多锻炼 锻炼有很多锻炼 一个练习有许多回路(包括重复/设置/重量)

一切正常

但现在我正在添加一个新的关系,我不知道如何建立。 我想有一个新的模式,一个用户有许多“已完成的训练”,其中包含了训练模式的所有属性

我的第一个想法是添加一个用户锻炼模型;为用户和训练使用外键。但这意味着每当我在训练中做出改变时,它也会反映在user.workouts中;这不是我想要的

schema.rb user.rb
class用户
附表1.rb
课程表
workout.rb
课堂训练
我可以想到两种可能的解决方案,都需要一定程度的数据冗余

解决方案1:添加存储训练表时间点副本的用户\u训练模型

在这种方法中,您可以按计划添加
user\u锻炼
模型,但您可以将所需的属性复制到
user\u锻炼
模型,而不是仅保留对
锻炼
的引用。这意味着当您的
锻炼
值以后发生变化时,您的
用户锻炼
将继续反映用户进行的锻炼的价值

表结构:

  • 用户id:integer
  • 训练id:整数(供参考)
  • 训练的所有其他栏目
  • 优点:

  • 即使训练更改,用户训练值也不会更改
  • 反对意见:

  • 重复数据(在这种情况下,在一定程度上需要重复数据)
  • 无论何时将新列添加到
    训练
    ,都需要将它们添加到
    用户训练
  • 但是,如果您只是为了显示目的而存储这些值,并且不打算对它们执行任何计算操作,您可以在
    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