我正在做一个小项目,以获得Ruby和RoR开发方面的更多技能。
现在我被卡住了,这让我抓狂。我在Stack Overflow和谷歌上寻找答案,但我认为我问错了问题。
想法:
- 用户可以创建并登录到他的帐户
- 用户可以创建一个包含以下字段的仪表板
- 标题
- 说明
- 每个仪表板包含四个预定义的检查表(类似类别)
- 这些检查表显示由任务定义的用户进度
- 每个检查表都包含预定义的任务集合(复选框)
- 这些任务就像用户必须完成的待办事项,所以我可以更新检查表上的进度(其中x项任务已完成。xy%已完成)
- 每个用户都有相同的复选框
问题:
- 我现在的问题是,在创建仪表板时,如何为每个用户创建和保存预定义的任务集,以及用户和检查表模型之间的正确关联
- 我对这四个模特的联想是对的吗?有其他更好的方法来设置吗
现状:
这些是模型和模式之间的关联。Rails的版本是4.2.6和Ruby 2.2.3。该应用程序正在使用postgres的docker容器中运行。
user.rb
class User < ActiveRecord::Base
has_many :dashboards, dependent: :destroy
has_many :tasks, :through => :checklists #Is this right?
has_many :identities, dependent: :destroy
validates_length_of :dashboards, :maximum => 1
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :omniauthable, :invitable, :database_authenticatable, :registerable,:recoverable, :rememberable, :trackable
end
仪表板.rb
class Dashboard < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
validates_uniqueness_of :title
validates_length_of :description, maximum: 300
end
任务.rb
class Task < ActiveRecord::Base
belongs_to :checklist
belongs_to :user
validates :user_id, presence: true
validates_uniqueness_of :title
validates_length_of :description, maximum: 300
end
schema.rb
ActiveRecord::Schema.define(version: 20160514200622) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "checklists", force: :cascade do |t|
t.string "title"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "dashboards", force: :cascade do |t|
t.string "title"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
add_index "dashboards", ["user_id"], name: "index_dashboards_on_user_id", using: :btree
create_table "tasks", force: :cascade do |t|
t.string "title"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "completed"
t.integer "checklist_id"
end
add_index "tasks", ["checklist_id"], name: "index_tasks_on_checklist_id", using: :btree
create_table "users", force: :cascade do |t|
t.string "email", default: ""
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "invitation_token"
t.datetime "invitation_created_at"
t.datetime "invitation_sent_at"
t.datetime "invitation_accepted_at"
t.integer "invitation_limit"
t.integer "invited_by_id"
t.string "invited_by_type"
t.integer "invitations_count", default: 0
end
add_foreign_key "dashboards", "users"
add_foreign_key "identities", "users"
add_foreign_key "tasks", "checklists"
end
我会感谢你帮我解决问题的。
您的建模有点偏离:
class User < ActiveRecord::Base
has_many :checklists, dependent: :destroy
has_many :tasks, through: :checklists
end
class Checklist
belongs_to :user
has_many :tasks, dependent: :destroy
end
class Task
belongs_to :checklist
has_one :user, through: :checklist
end
这里的检查表是一个连接模型,允许用户和任务之间建立间接关系。
并不是说在使用through
选项时,您实际上必须声明它应该经过的关系:
# has_many :checklists
has_many :tasks, through: :checklists # Error!
当设置从任务返回到用户的关系时,您希望使用has_one
而不是belongs_to
。
class Task
belongs_to :checklist
has_one :user, through: :checklist # points to checklists.user_id
end
而不是belongs_to :user
,因为你不想把user_id
列放在两个地方,因为ActiveRecord不会让tasks.user_id
保持最新!幸运的是,您无论如何都没有创建tasks.user_id
列。