- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个简单的任务列表应用程序,上面有用户和列表,用户由 Devise 管理,可以创建任务列表,以及其他用户或他们自己创建的收藏夹列表。用户和列表之间的所有权关系很容易建立,但我无法建立用户喜欢列表的关系。我设想它毕竟是一个多对多关系,一个用户可以收藏多个列表,一个列表可以被许多用户收藏,这种关系发生在另一个已经存在的列表所有权的一对多关系之上用户让我犹豫了一下,这是否是一个好的做法,但我还是继续尝试。
目前我有两种模型,一种用于用户,一种用于列表,我尝试通过运行 rails g migration CreateJoinTableFavorites users lists
来为收藏夹创建迁移。 , 这导致了以下迁移
class CreateJoinTableFavorites < ActiveRecord::Migration[5.2]
def change
create_join_table :users, :lists do |t|
t.index [:user_id, :list_id] <-- I uncommented this line
# t.index [:list_id, :user_id]
t.timestamps <-- I added this line
end
end
end
我原以为这会创建一个名为“Favorites”的表,自动链接用户和列表,但实际上它创建了一个名为“lists_users”的表。现在我不知道下一步该怎么做。我读到我需要为此连接表创建一个模型,但我不知道该怎么做。我运行什么命令? rails g model Favorites
? rails g model ListsUsers
?我是否还要告知我要添加的字段,例如 rails g model Favorites user_id:integer list_id:integer
,或者是否有其他更好的方法,例如 rails g model Favorites user:references list:references
?这里的最佳实践是什么
除此之外,我还在 list#show
中添加了一个按钮 View 供用户单击以将该列表添加到他们的收藏夹,并且在路由它时遇到了一些麻烦。我所做的是创建一个这样的按钮:
<%= button_to 'Add to favorites', add_favorites_path({list_id: @list.id}), method: :post %>
还有一条新路线:
post 'add_favorites', to: 'lists#add_favorites'
虽然我设法访问了该操作中的列表 ID 和用户 ID,但现在我不知道如何继续在我的 lists_users
中创建“收藏夹”数据库条目。 table 。为了说明,我将在此处粘贴我的“add_favorite”操作
def add_favorites
user_id = current_user.id
list_id = params[:list_id]
#TODO: create the relation in lists_items table
end
我知道如果没有连接表的模型我无法让它工作,但即使我有那个模型,我也没有太多运气来寻找在 Controller 中做什么来创建它关系。不管怎样,我的模型如下:
class List < ApplicationRecord
belongs_to :user
has_many :users, through: :lists_users
end
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :lists
has_many :lists, through: :lists_users
end
总而言之,我知道我缺少连接表的模型,我想一步一步地了解如何创建它、给它起什么名字等等,以及如何在我的 Controller 中继续我的操作以创建一个新的收藏条目
最佳答案
有两种方法可以在 Rails 中创建多对多关系。您所做的似乎将两者混为一谈,我怀疑这是问题的根源。
简而言之,这两种方法是:
1) has_many :other_models, through: :relation
或
2) has_and_belongs_to_many :other_models
主要区别在于“has_many through”方法期望连接表是一个单独的模型,如果需要可以独立于此关系进行处理,而“has_and_belongs_to_many”方法不要求连接表具有对应型号。在后一种情况下,您将不能独立处理连接表。 (顺便说一句,这使得连接表上的时间戳变得无用。)
您应该使用哪种方法取决于您的用例。 docs很好地总结标准:
The simplest rule of thumb is that you should set up a has_many :through relationship if you need to work with the relationship model as an independent entity. If you don't need to do anything with the relationship model, it may be simpler to set up a has_and_belongs_to_many relationship (though you'll need to remember to create the joining table in the database). (emphasis added)
现在回答您的问题:当您使用 create_join_table
时,您将其视为正在为 has_and_belongs_to_many 关系进行设置。 create_join_table
将创建一个名为 "#{table1}_#{table2}"
的表,其中的 ID 指向这些表。它也按字母顺序排列它们,这就是为什么你得到“lists_users”而不是“users_lists”的原因。如果您计划使用 has_and_belongs_to_many
,这实际上是 Rails 连接表的标准命名约定,通常不应重命名。
如果您真的想使用has_and_belongs_to_many
,请使用create_join_table
保持迁移并在您的模型中执行以下操作:
# user.rb
class User
has_and_belongs_to_many :lists
end
# list.rb
class List
has_and_belongs_to_many :users
end
瞧。不需要 Favorite
模型,而且 Rails 足够智能,可以通过自己的表处理关系。虽然更容易一些,但缺点是,如上所述,您将无法将连接表作为一个独立的模型来处理。 (同样,连接表上的时间戳在这种情况下没有用,因为 Rails 不会设置它们。)
编辑:由于您不能直接接触 lists_users,因此您可以通过在用户上设置列表关系或在列表上设置用户关系来创建关系,如下所示:
def add_favorites
list = List.find(params[:list_id])
current_user.lists << list # creates the corresponding entry in lists_users
# Don't forget to test how this works when the current_user has already favorited a list!
# If you want to prevent that from happening, try
# current_user.lists << list unless current_user.lists.include?(list)
# Alternatively you can do the assignment in reverse:
# list.users << current_user
# Again, because the join table is not an independent model, Rails won't be able to do much to other columns on lists_users out of the box.
# This includes timestamps
end
另一方面,如果您想使用“has_many through”,请不要使用create_join_table
。如果你正在使用 has_many through,连接表应该被认为几乎是一个完全独立的模型,它恰好有两个外键并将两个其他模型以多对多关系连接在一起。在这种情况下,你会做类似的事情:
# migration
class CreateFavorites < ActiveRecord::Migration[5.2]
def change
create_table :favorites do |t|
t.references :list
t.references :user
t.timestamps
end
end
end
# user.rb
class User
has_many :favorites
has_many :lists, through: :favorites
end
# list.rb
class List
has_many :favorites
has_many :users, through: :favorites
end
# favorite.rb
class Favorite
belongs_to :list
belongs_to :user
end
# controller
def add_favorites
# You actually have a Favorite model in this case, while you don't in the other. The Favorite model can be more or less independent of the List and User, and can be given other attributes like timestamps.
# It's the rails methods like `save`, `create`, and `update` that set timestamps, so this will track those for you as any other model.
Favorite.create(list_id: params[:list_id], user: current_user)
end
您可能想考虑使用哪种方法。同样,这实际上取决于您的用例和上述标准。就我个人而言,当我不确定时,我更喜欢“has_many through”方法,因为它为您提供了更多的工作工具并且通常更灵活。
关于ruby-on-rails - 在 Rails 上创建多对多记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57015988/
sanitize 是什么意思在 Rails 中是什么意思? 我正在阅读 CanCanCan 的文档.它说: When using strong_parameters or Rails 4+, you
在过去的几个月里,我感觉自己对 Ruby on Rails (RoR) 开发的了解达到了极限。我为大/小客户和 friend /爱好项目开发了大大小小的应用程序。我知道如何开发这些应用程序,但开始感觉
我昨天参加了一个关于扩展 Rails 的聚会,其中一个主题是 Hexagonal Rails。然而,我只做了一年的 Rails,对 MVC 结构非常满意(也许太舒服了),所以我不太了解适配器和消息队列
我使用多个 Rails 应用程序,一些在 Rails 3.2/Ruby 2.0 上,一些在 Rails 2.3/Ruby 1.8.7 上。 他们的共同点是,随着他们的成长和添加更多的依赖项/ gem
这个问题在这里已经有了答案: Using Rails-UJS in JS modules (Rails 6 with webpacker) (5 个答案) 关闭 3 年前。 我正在尝试使用 UJS
我正在开发一个当前使用 Rails 1.2 的 Rails 应用程序,所以我现在离最新的稳定版本(Rails 2.3)还有很长的路要走。 我应该如何进行迁移到更新版本的 Rails 的过程? 我应该一
尝试按照 Ryan Bates Backbone.js 教程构建抽奖应用程序,但我已经遇到了第一段代码的问题。在 application.js 的 init 函数中,他初始化了 Raffler 路由的
我正在使用 Rails 3.2 并且我有一个数据库表,我想在其中找到符合以下条件的所有行: a = true and b = true and ( 0 true, :b =>
我有一个用户类和一个联系人,其中联系人是用户的子类。这两个类都存储在用户表中。 我的联系人可能有也可能没有电子邮件地址,而我的用户需要一个电子邮件地址(我的用户模型定义中有 validates_pre
我正在编写一个教程,我在其中演示了一些 rails 命令。在我的机器上 rails和 script/rails两者都同样有效。有“首选”形式吗?两者中哪一个更普遍? 最佳答案 当您运行 rails 时
我正在寻找有关通过我的应用程序前进的最佳方式的建议,这是我首次开始集成Elasticsearch。我是一名初学者,但是热衷于深入研究,以便原谅任何明显的错误! 我遵循了http://www.sitep
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我刚刚用 Rails new 启动了一个新的 Rails 应用程序,将默认数据库设置更改为 PostgresSQL。我用 bin/rails s 启动服务器,结果很奇怪 2016-04-21 05:0
我收到一个参数并希望它是这样的字符串: "abc,efg" 或者像这样的数组 ["abc","efg"] 在第一种情况下,我想将它转换成一个数组,什么是好的方法? 这是我的想法 if params[:
我有 Rails 4,这是我的默认版本(我仍然希望它是)。但我不想在我的电脑上添加 rails 3.2。在以下命令中:gem install rails -v 3.2.16 我有这个警告: railt
您好,我想使用 Sheevaplug 构建一个“Rails Brick”来自 Marvell(操作系统是开箱即用的 Ubuntu,但您可以在其上安装其他发行版)。它将成为家庭服务器和静音、低成本(99
我需要能够从 Rails 控制台发送我的 Rails 应用程序的 Postgres 数据库中所有未接受的邀请。 (我有一个名为 Invitations 的表,其中包含一个名为 accepted 的 b
validate :cannot_modify_if_locked, on: :update def cannot_modify_if_locked if self.locked erro
我正在学习教程(学习 Rails 播客),需要更改以下路由语法,以便它与 Rails 3.0 兼容。谁能帮忙? map.view_page ':name', :controller => 'viewe
我是一名优秀的程序员,十分优秀!