【问题标题】:how to create a record for a join table?如何为连接表创建记录?
【发布时间】:2020-08-18 10:22:33
【问题描述】:

我设置了以下关联:

class Book < ActiveRecord::Base
    belongs_to :author
    belongs_to :category
    has_many :users_books
    has_many :users, through: :user_books
end

class User < ActiveRecord::Base
    has_many :users_books
    has_many :books, through: :users_books
end

我按照我应该的方式创建了一个连接表迁移

class CreateUsersBooks < ActiveRecord::Migration[4.2]
    def change
      create_table :users_books do |t|
        t.integer :user_id
        t.integer :book_id
      end
    end
  end

现在我需要创建一个名为 check_out_book 的方法,它接受一本书和一个到期日期作为参数。当用户签出一本书时,它应该创建一个新的 UserBook 记录(或 Checkout 记录或任何您想调用的连接表/模型)。那个新的 UserBook 记录应该有一个返回的属性(以及表列)?这应该默认为假。我将如何着手创建此方法和迁移?

【问题讨论】:

  • 您的users_books 表也是模型还是只是表?
  • due_datereturned 列添加到表中。
  • 感谢@AmitPatel!我将如何在该实例方法中创建 UserBook 的新记录?
  • @max 在下面的回答中解释了。

标签: ruby-on-rails ruby join activerecord migration


【解决方案1】:

您在 Rails 中的表名和关联应始终为 singular_plural,除了(非常没用的)has_and_belongs_to_many 关联使用的奇怪的小鸭“无头”连接表。

class CreateUserBooks < ActiveRecord::Migration[4.2]
  def change
    create_table :user_books do |t|
      t.references :user
      t.references :book
      t.boolean :returned, default: false
    end
  end
end
class UserBook < ActiveRecord::Base
  belongs_to :user
  belongs_to :book
end
class Book < ActiveRecord::Base
    belongs_to :author
    belongs_to :category
    has_many :user_books
    has_many :users, through: :user_books
end
class User < ActiveRecord::Base
    has_many :user_books
    has_many :users, through: :user_books
end

但是你真的应该使用一个更好的更具描述性的名称,告诉其他程序员这在域中代表什么,而不仅仅是它加入的两个模型的合并,例如 Loan 或 Checkout。

我还将使用t.datetime :returned_at 创建一个日期时间列,该列可以记录图书实际归还的时间,而不仅仅是一个布尔值。

如果您想使用除外键之外的任何其他数据创建连接记录,则需要显式创建而不是隐式创建(例如通过user.books.create())。

@book_user = Book.find(params[:id]).book_users.create(user: user, returned: true)
# or
@book_user = current_user.book_users.create(book: user, returned: true)
# or
@book_user = BookUser.new(user: current_user, book: book, returned: true)

【讨论】:

  • 指令要求在 User 类的实例方法中创建 UserBook 记录。所以如果我理解正确,那是不可能的?
  • 不,你误会了。没有什么能阻止您在实例方法中创建它。当您通过 books.users &lt;&lt; user 等方法隐式创建连接表记录时,无法添加任何元数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
  • 2018-01-12
  • 1970-01-01
相关资源
最近更新 更多