我正在尝试使嵌套表格起作用。这是“新专辑”的一种形式,在其下方可以写评论。当我在表单上按Submit时,只有一个错误,该表单保持显示在页面上,但弹出一个错误,提示“必须存在评论用户”。 >>> shown here
日志:
Started POST "/albums" for ::1 at 2020-04-19 11:48:09 -0400
Processing by AlbumsController#create as HTML
Parameters: {"authenticity_token"=>"icNyGWd34iCxPgmpkA2vORQOrRHwk8eXvjbzuaU3j4Q8dlMof496s8wjA1uVdW8gJCbjfKfhLx1jBn8WIu8/yA==", "album"=>{"artist"=>"Blink 182", "title"=>"California", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x00007fc373b0de00 @tempfile=#<Tempfile:/var/folders/26/p006tryd6yb9sp9rq446p07c0000gn/T/RackMultipart20200419-64975-tegau2.jpg>, @original_filename="71GfPCWJHXL._SL1500_.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"album[avatar]\"; filename=\"71GfPCWJHXL._SL1500_.jpg\"\r\nContent-Type: image/jpeg\r\n">, "reviews_attributes"=>{"0"=>{"title"=>"B182 REVIEW", "date"=>"2020-04-19", "content"=>"VERY BAD, b182 sucks now, where is tom bring back tom"}}}, "commit"=>"Create Album"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 11], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:10:in `current_user'
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 11], ["LIMIT", 1]]
↳ app/controllers/albums_controller.rb:25:in `create'
(0.1ms) begin transaction
↳ app/controllers/albums_controller.rb:28:in `create'
Review Exists? (2.3ms) SELECT 1 AS one FROM "reviews" WHERE "reviews"."title" = ? LIMIT ? [["title", "B182 REVIEW"], ["LIMIT", 1]]
↳ app/controllers/albums_controller.rb:28:in `create'
(0.1ms) rollback transaction
↳ app/controllers/albums_controller.rb:28:in `create'
Rendering albums/new.html.erb within layouts/application
Rendered albums/_form.html.erb (Duration: 6.2ms | Allocations: 1814)
Rendered albums/new.html.erb within layouts/application (Duration: 6.4ms | Allocations: 1878)
[Webpacker] Everything's up-to-date. Nothing to do
Rendered layouts/_navigation.html.erb (Duration: 0.5ms | Allocations: 100)
Completed 200 OK in 41ms (Views: 19.4ms | ActiveRecord: 2.7ms | Allocations: 13088)
嵌套表格(albums / _form.html.erb)
<%= form_for(@album) do |f| %>
<% if @album.errors.any? %>
<ul>
<% @album.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<%= f.label :artist %>
<%= f.text_field :artist %>
<br><br>
<%= f.label :title %>
<%= f.text_field :title %>
<br><br>
<%= f.label "Album Image:" %><br>
<%= f.file_field :avatar %>
<br><br>
<h2>Write your review of the album</h2>
<%= f.fields_for :reviews do |ff| %>
<%= ff.label :title %>
<%= ff.text_field :title %>
<br>
<%= ff.label :date %>
<%= ff.date_field :date %>
<br>
<%= ff.label :content %>
<%= ff.text_area :content %>
<% end %>
<br>
<%= f.submit %>
<% end %>
<br><br><br>
<%= link_to "Back to Album", albums_path(@album) %>
相册控制器:
class AlbumsController < ApplicationController
before_action :set_album, only: [:show, :edit, :update, :destroy]
before_action :must_login, only: [:new, :show, :create, :edit, :update, :destroy]
def index
@albums = Album.all
@user = current_user
end
def show
@review = @album.reviews.build
@review.user = current_user
@review.save
@reviews = Review.recent #scope
end
def new
@album = Album.new
@review = @album.reviews.build
@user = current_user
end
def create
@user = User.find(current_user.id)
@album = current_user.albums.build(album_params)
@album.user_id = current_user.id
if @album.save
redirect_to album_path(@album)
else
render :new
end
end
def edit
@user = current_user
end
def update
#@album = current_user.albums.build(album_params)
@album.user_id = current_user.id
if @album.update(album_params)
redirect_to album_path(@album), notice: "Your album has been updated."
else
render 'edit'
end
end
def destroy
@album.delete
@album.avatar.purge
redirect_to albums_path
end
private
def set_album
@album = Album.find(params[:id])
end
def album_params
params.require(:album).permit(:artist, :title, :avatar, :user_id, reviews_attributes:[:title, :date, :content, :user_id, :album_id])
end
end
评论控制器
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
before_action :set_current_user, only: [:index, :new, :edit, :destroy]
before_action :find_album, only: [:create, :edit, :update, :destroy]
before_action :must_login, only: [:index, :new, :create, :edit, :update, :destroy]
def index
@albums = Album.with_recent_reviews
end
def show
#@reviews = Review.where("album_id = ?", params[:album_id])
end
def new
if params[:album_id] && @album = Album.find_by(id: params[:client_id])
@review = @album.reviews.build
else
redirect_to albums_path
end
end
def create
@review = current_user.reviews.build(review_params)
@review.album = @album
if @review.save
redirect_to album_path(@album)
else
@album = @review.album
render :new
end
end
def edit
end
def update
if @review.update(review_params)
redirect_to album_path(params[:album_id])
else
render 'edit'
end
end
def destroy
if current_user.id == @review.user_id
@album.reviews.find(params[:id]).destroy
redirect_to album_path(params[:album_id])
else
flash[:error] = "Unable to delete your review. Please try again."
redirect_to album_reviews_path(@review)
end
end
private
def set_review
@review = Review.find(params[:id])
end
def set_current_user
@user = current_user
end
def find_album
@album = Album.find(params[:album_id])
end
def review_params
params.require(:review).permit(:title, :date, :content, :user_id, :album_id, album_attributes:[:artist, :title, :user_id])
end
end
专辑模型:
class Album < ApplicationRecord
has_many :reviews
has_many :users, through: :reviews
has_one_attached :avatar
accepts_nested_attributes_for :reviews
validates_presence_of :artist
validates_presence_of :title
scope :with_recent_reviews, -> { includes(:reviews).where(reviews: { date: [(Date.today - 7.days)..Date.tomorrow] }) } #scope relies on include method and custom query on related model (reviews)
end
查看模型:
class Review < ApplicationRecord
belongs_to :album, optional: true #<<<< i think this line saved my life
belongs_to :user
validates_presence_of :content
validates :title, presence: true, uniqueness: true
validates :date, presence: true
accepts_nested_attributes_for :album
scope :recent, -> { where("date(date) >= ?", Date.today - 7.days) } #scope
end
Routes.rb
Rails.application.routes.draw do
get '/auth/:provider/callback' => 'sessions#omniauth'
get 'auth/failure', to: redirect('/')
get '/signup' => 'users#new', as: 'signup'
post '/signup' => 'users#create'
get '/signin' => 'sessions#new'
post '/signin' => 'sessions#create'
get '/signout' => 'sessions#destroy'
post '/logout', to: "sessions#destroy"
resources :albums do
resources :reviews, except: [:index]
end
resources :users, only: [:show, :destroy]
resources :reviews, only: [:index]
root to: "albums#index"
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
reviews
关联是has_many,所以fields_for应该使用复数形式。
= f.fields_for :reviews do |ff|
这样,rails就会创建您允许的参数reviews_attributes
。
如果该更改仍然有问题,请显示新的错误和堆栈跟踪。