Rails嵌套表单不会保留数据

问题描述 投票:0回答:1

我正在尝试使嵌套表格起作用。这是“新专辑”的一种形式,在其下方可以写评论。当我在表单上按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

ruby-on-rails parameters nested-forms
1个回答
0
投票

reviews关联是has_many,所以fields_for应该使用复数形式。

= f.fields_for :reviews do |ff|

这样,rails就会创建您允许的参数reviews_attributes

如果该更改仍然有问题,请显示新的错误和堆栈跟踪。

© www.soinside.com 2019 - 2024. All rights reserved.