Rails form_for вложенные формы не создаются / сохраняются

#ruby-on-rails #crud #nested-forms #form-for

#ruby-on-rails #crud #вложенные формы #форма-для

Вопрос:

Вот мои модели:

 class Drama < ApplicationRecord
has_many :reviews 
has_many :users, :through => :reviews
validates :name, uniqueness: true 
accepts_nested_attributes_for :reviews
accepts_nested_attributes_for :users 
 

завершение

 class Review < ApplicationRecord
belongs_to :user 
belongs_to :drama 
 

завершение

класс User <ApplicationRecord has_many :отзывы has_many:драмы, :через => :отзывы проверяет:имя пользователя, уникальность: true, наличие: true проверяет:email, уникальность: true, присутствие: true has_secure_password конец

Вот вложенная форма, которая просто не сохраняется / не создается!

  <div>
<%= form_for @drama do |f| %>

<h2>Drama Info</h2>

<strong>Name: <%= f.text_field :name %></strong><br>
<strong>Genre: <%= f.text_field :genre %></strong><br>


<h2>Review Info</h2>

<%= f.fields_for :reviews, @drama.reviews.build do |r| %>
<%= r.label :title %>
<%= r.text_field :title %><br>

<%= r.label :rating %>
<%= r.number_field :rating %><br>

<%= r.label :content %>
<%= r.text_area :content %><br>
<%end%>

<%= f.submit %>
<%end%>
</div>
 

Вот мои маршруты:

  Rails.application.routes.draw do

  resources :dramas do
    resources :reviews, only: [:new, :show]
  end

  resources :dramas 
  resources :users
  resources :reviews 

  get '/auth/facebook/callback', to: 'sessions#create_with_fb'

  get '/', to: 'sessions#home'
  get '/signup', to: 'users#new'
  post '/signup', to: 'users#create'
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'
  post '/logout', to: 'sessions#destroy'
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
 

Вот мой контроллер dramas:

 class DramasController < ApplicationController
before_action :find_by_drama, only: [:edit, :update, :destroy, :show]
before_action :current_user, only: [:create, :update, :edit, :destroy]
def index 
    @dramas = Drama.all 
end 

def new    
    @drama = Drama.new 
    @drama.reviews.build 
end  


def show 
    session[:drama_id] = @drama.id
   # @drama = Drama.find(session[:drama_id])
end 

def create 
    @drama = Drama.new(drama_params)
    if @drama.save 
        redirect_to dramas_path
    else 
        render :new 
end 
 

завершение

 def update 
    @drama = Drama.update(drama_params)
    redirect_to dramas_path 
end 

def edit 
end 

def destroy 
    @drama.destroy 
    redirect_to dramas_path 
end 


private 

def drama_params
    params.require(:drama).permit(
        :name,
        :genre,
        reviews_attributes: [
            :title,
            :rating,
            :content
          ]
    )
end 
 

завершение

Моя db. schema :

 ActiveRecord::Schema.define(version: 2020_12_19_073757) do

  create_table "dramas", force: :cascade do |t|
    t.string "name"
    t.string "genre"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "reviews", force: :cascade do |t|
    t.integer "user_id"
    t.integer "drama_id"
    t.string "title"
    t.text "content"
    t.integer "rating"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "email"
    t.string "password_digest"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

end
 

Пожалуйста, помогите! Застрял

Ответ №1:

Внутренняя @drama.reviews.build часть fields_for не нужна, поскольку вы уже создали обзор в new действии. Попробуйте удалить его и посмотреть, работает ли он. Затем в edit действии добавьте @drama.reviews.build , если вы хотите создать еще один обзор в этом действии. Создание вложенных атрибутов в представлении может привести к некоторому странному поведению. Если это все еще не работает, отправьте трассировку из запущенного приложения или попробуйте @drama.errors.inspect либо в представлении, либо использовать puts для печати ошибок в журналах сервера.