Rails 查看与另一个模型相关的模型数据

时间:2021-04-19 21:33:39

标签: ruby-on-rails

所以我刚刚学习 Ruby on Rails,我遇到了一个与查看模型数据相关的问题。

我有 2 个模型,ProductReview。由于产品可以有许多评论,因此关系设置为产品 has_many 评论和评论 has_one 产品。

我正在尝试在产品详细信息页面上显示产品的所有评论。我在产品的展示视图中添加了一个评论表。然后我将 @reviews=@product.reviews 添加到我的 show 定义中。

发生的情况是,我收到了贯穿每条评论的循环错误 <% @reviews.each do |review| %> 说明 Unknown column 'reviews.product_id'

在我的产品模型中,我有一个名为 ProductId 的列,我认为它是应用程序检索产品评论列表的方式,但事实并非如此。这 product_id 只是框架创造的独特价值吗?

只是想知道是我做错了什么还是我没有实施。

Show.html.erb;

Show.html.erb

显示定义;

Show definition in controller

我的评论表定义是 schema.rb;

create_table "reviews", charset: "utf8mb4", force: :cascade do |t|
t.integer "ProfileId"
t.integer "ProductId"
t.string "Author"
t.integer "ProductRating"
t.string "ReviewText"
t.date "DateofReview"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

我的产品表定义是 schema.rb;

create_table "products", charset: "utf8mb4", force: :cascade do |t|
t.string "pName"
t.string "pBrand"
t.integer "pCost"
t.string "pCategory"
t.datetime "pDate"
t.string "pDescription"
t.string "pPhoto"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

2 个答案:

答案 0 :(得分:0)

rails 中数据库的约定和默认列是snake_case https://edgeguides.rubyonrails.org/active_record_basics.html#schema-conventions 即使在使用camelCase 时它不会失败,就像在您的情况下,您可能需要更改很多区域,而在您的情况下,这里has_many 正在寻找基于 class + _id 的外键来解决这个问题,您需要在那里指定外键:

has_many :reviews, foreign_key: :ProductId

和 has_one 上的外键,还要注意,在您的情况下,这应该是 belongs_to,因为键位于评论表中 https://guides.rubyonrails.org/association_basics.html#the-belongs-to-association

belongs_to :product, foreign_key: :ProductId

答案 1 :(得分:0)

您的迁移不正确。 Rails works on conventions。它不使用StudlyCaps,它使用snake_case。它期望列是 product_id,而不是 ProductId。除非您要使 Rails 适应现有架构,否则最好遵循 Rails 约定。

迁移应如下所示:

# Prefer Symbols to Strings.
# See https://medium.com/@lcriswell/ruby-symbols-vs-strings-248842529fd9
# force: :cascade is questionable.
create_table :reviews, charset: :utf8mb4 do |t|
  # Declare profile_id and product_id as indexed foreign keys
  # Declare them `not null`, a review must have a reviewer and product.
  t.belongs_to :profile, foreign_key: true, null: false
  t.belongs_to :product, foreign_key: true, null: false

  # Assuming Profile is the author of the review, Author is redundant.

  # Drop the "product" prefix, we know from context what its rating.
  # Presuming a review needs a rating, set it `not null`.
  t.integer :rating, null: false

  # Presuming a review needs a body, set it `not null`.
  # Drop the "review" prefix from "review_text". "text" is too generic.
  # It's the body of the review.
  t.text :body, null: false

  # DateOfReview is redundant with the created_at timestamp

  # The standard created_at and updated_at timestamps
  t.timestamps
end
# Don't prefix columns, its confusing and obfuscating,
# especially when applied inconsistently.
# Use table aliases and fully qualified column names instead.
# In Rails you will rarely be writing SQL by hand anyway.
create_table :products, charset: :utf8mb4 do |t|
  # Presuming a product requires a name and cost, make them `not null`.
  t.string :name, null: false
  t.integer :cost, null: false

  # Consider referencing categories and brands tables instead. It would make
  # listing them and querying products by them faster and easier, and
  # protects against typos.
  t.string :brand
  t.string :category

  # Large blocks of text should be "text" not "string".
  # string is varchar, text is text.
  t.text :description

  # Do not store binaries in the database. It is slow and bloated.
  # Use ActiveStorage instead.
  # https://guides.rubyonrails.org/active_storage_overview.html
  t.string :photo

  # pDate is redundant with created_at

  t.timestamps
end

has_one 在这里不合适。那是当你可以拥有很多,但只有一个的时候。例如,如果一个产品只能有一个评论,您就会使用它。

相反,对于简单的一对多关系,评论 belongs_to 产品。

class Review < ApplicationRecord
  belongs_to :product
end

class Product < ApplicationRecord
  has_many :reviews
end

一般来说,generate your models 获取基础知识,然后对其进行编辑。

例如,您可以像这样生成产品和评论,然后编辑生成的文件。

$ rails g model Product name:string cost:integer description:text
$ rails g model Review product:belongs_to rating:integer
相关问题