我正在尝试构建Rails应用程序。我正在尝试构建一个使用作者和书籍的应用程序。该应用程序的目的是为“书籍”提供一个显示页面,为“作者”提供一个显示页面,以及将两者连接的一些链接。我快准备好了。我唯一的问题是,每当我尝试保存作者姓名时,都将其保存为指向作者页面的链接。
这是我开始的目的: schema.rb
ActiveRecord::Schema.define do
create_table "books", force: :cascade do |t|
t.string "title"
t.integer "author_id"
t.string "author_name"
t.index ["title"], name: "index_books_on_title", unique: true
end
create_table "authors", force: :cascade do |t|
t.string "name"
t.string "bio"
end
end
这是我在seeds.rb中的样本数据
books = [
{title:"Ruby Programming", author_id: 1, author_name: "John Smith"},
{title:"Java Programming", author_id: 2 , author_name: "Jane Adams"},
{title:"PHP Programming", author_id: 3, author_name: "Mike Jones"},
{title:"Python Programming", author_id: 1, author_name: "John Smith"}
]
authors = [
{name:"John Smith", bio: "John Smith loves Ruby and Python"},
{name:"Jane Adams", bio: "Jane Adams loves Java"},
{name:"Mike Jones", bio: "Mike Jones loves PHP"}
]
这是我的books_controller.rb
class BooksController < ApplicationController
def index
@books = Books.all
if params[:search]
@books = Book.search(params[:search]).order("created_at DESC")
else
@books = Book.all.order("created_at DESC")
end
end
def show
@book = Book.find(params[:id])
end
def new
@book = Book.new
end
def create
@book = Book.new(book_params)
if(@book.save)
redirect_to @book
else
render 'already_exists'
end
end
private def book_params
params.require(:book).permit(:id, :title, :author_id, :author_name)
end
end
这是我的author_controller.rb
class AuthorsController < ApplicationController
def index
@authors = Author.all
end
def show
@author = Author.find(params[:id])
end
end
这是我的模型/book.rb
class Book < ApplicationRecord
has_one :author
validates :title, presence:true, length: {minimum:1}
end
这是我的模型/author.rb
class Superpower < ApplicationRecord
has_many :books
end
因此,我正在努力做到这一点,以便用户可以与选定的作者之一一起创建新书。创建书籍后,他们将被重定向回一个新页面,该页面将显示书籍的标题和作者的姓名(它将链接至作者的页面及其个人简介)。
这是views / books / new.html.erb
<h1> Add Book </h1>
<%= form_for :book, url: books_path do |f| %>
<p>
<%= f.label :title %> <br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :author_id, "Author" %> <br>
<%= collection_select(:book, :author_id, Author.all, :id, :name, {:prompt => 'Please select'}, class: 'form-control' ) %>
</p>
<p>
<%= f.submit %>
<p>
<% end %>
这是views / book / show.html.erb
<h2> Title: <%= @book.title %> </h2>
<h2> Author: <%= link_to @book.author_name, author_path(@book.author_id) %> </h2>
<p> <%= link_to "Go back to Books", root_path %> </p>
但不显示此内容:
Title: Ruby Programming
Author: John Smith
我明白了:
Title: Ruby Programming
Author: authors/1
我怀疑这与我选择作者的表单有关,但是我不知道为什么“ author_name”没有保存为author_name字符串,而是保存为指向作者页面的直接链接。这个错误弄乱了我的应用程序的其他部分,而我已经困扰了几天。有人可以协助吗?
答案 0 :(得分:0)
您生成的方式不是本书的author_name字段的正确方式,但是根本不需要它,如果存在关系并且author表具有name字段,则始终可以使用book_instance.author.name ,也可以在书本模型中生成方法author_name,并返回该方法。
因此,通过迁移从书本表中删除author_name字段,将其从控制器中的强参数中删除,然后将下一个方法添加到书本模型中:
def author_name
self.author.name
end
这应该有效
答案 1 :(得分:0)
两种解决方法:
before_create :set_author_name
OR
before_validation(on: :create) do
set_author_name
end
并在图书模型中定义以下方法:
def set_author_name
self.author_name = self.author.name
end
另一点,在Book模型中,它应该是belongs_to :author
而不是has_one :author
。
希望这会有所帮助。