Я создаю блог и столкнулся с проблемой при добавлении категорий. Я реализовал два способа добавления новых категорий: отдельная форма и вложенная форма внутри сообщения. Все существующие категории отображаются с флажками под формой публикации, а также есть поле для добавления новой категории в форму публикации. Если я выберу одну категорию и создаю новую одновременно - обе записи попадут в базу данных. Но когда я редактирую сообщение и удаляю или меняю категории, текстовое поле, предназначенное для вставки нового имени категории, содержит ранее примененное имя категории (или несколько полей с именами): вот как это выглядит
Как сделать так, чтобы текстовые поля не отображали существующие категории?
А также: я все еще могу удалить категории, удалив весь текст из полей и сняв флажки в форме редактирования. Изменения сохраняются, а категории удаляются, но я вижу проблему «Недопустимый параметр:: id» в консоли, но не могу понять, почему она появляется:
Started PATCH "/articles/13" for ::1 at 2020-04-30 09:44:50 -0700
Processing by ArticlesController#update as HTML
Parameters: {"authenticity_token"=>"J3hKH7WV9ojLBim+tpI40lfUrnA2raRjccmPIigqaTFTMvsE9kv3i/CXwcoB89w/expi3NiX4jjnjNjobe7l1A==", "article"=>{"title"=>"tatata", "description"=>"tatatta", "category_ids"=>[""], "categories_attributes"=>{"0"=>{"name"=>"", "id"=>"8"}}}, "commit"=>"Update Article", "id"=>"13"}
Article Load (0.2ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT ? [["id", 13], ["LIMIT", 1]]
↳ app/controllers/articles_controller.rb:50:in `set_article'
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 12], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:6:in `current_user'
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 12], ["LIMIT", 1]]
↳ app/controllers/articles_controller.rb:58:in `require_same_user'
Unpermitted parameter: :id
(0.0ms) begin transaction
↳ app/controllers/articles_controller.rb:28:in `update'
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE 1=0
↳ app/controllers/articles_controller.rb:28:in `update'
Category Load (0.1ms) SELECT "categories".* FROM "categories" INNER JOIN "article_categories" ON "categories"."id" = "article_categories"."category_id" WHERE "article_categories"."article_id" = ? [["article_id", 13]]
↳ app/controllers/articles_controller.rb:28:in `update'
ArticleCategory Destroy (0.8ms) DELETE FROM "article_categories" WHERE "article_categories"."article_id" = ? AND "article_categories"."category_id" = ? [["article_id", 13], ["category_id", 8]]
↳ app/controllers/articles_controller.rb:28:in `update'
(132.6ms) commit transaction
↳ app/controllers/articles_controller.rb:28:in `update'
Redirected to http://localhost:3000/articles/13
Completed 302 Found in 142ms (ActiveRecord: 134.0ms | Allocations: 6817)
Вот код (Rails 6):
article.rb
class Article < ApplicationRecord
belongs_to :user
has_many :article_categories
has_many :categories, through: :article_categories
accepts_nested_attributes_for :categories, allow_destroy: true, reject_if: lambda {|attributes| attributes[:name].blank?}
validates :title, presence: true, length: {minimum: 3, maximum: 50}
validates :description, presence: true, length: {minimum: 3, maximum: 2500}
validates :user_id, presence: true
validates_associated :categories
end
article_controller.rb
class ArticlesController < ApplicationController
before_action :set_article, only: [:edit, :update, :show, :destroy]
before_action :require_user, except: [:index, :show]
before_action :require_same_user, only: [:edit, :update, :destroy]
def index
@articles = Article.paginate(page: params[:page], per_page: 5).order('created_at DESC')
end
def new
@article = Article.new
@article.categories.build
end
def show
end
def destroy
@article.destroy
flash[:danger] = "Article was successfully deleted"
redirect_to articles_path
end
def edit
end
def update
if @article.update(article_params)
flash[:success] = "Article was successfully updated"
redirect_to article_path(@article)
else
render 'edit'
end
end
def create
@article = Article.new(article_params)
@article.user = current_user
if @article.save
flash[:success] = "Article was successfully created"
redirect_to article_path(@article)
else
render 'new'
end
end
private
def set_article
@article = Article.find(params[:id])
end
def article_params
params.require(:article).permit(:title, :description, categories_attributes: [:name, :destroy], category_ids: [])
end
def require_same_user
if current_user != @article.user and !current_user.admin?
flash[:danger] = "You can only edit and delete your own articles"
redirect_to root_path
end
end
end
Форма для новой категории в \ article_form. html .rb
<div class="col-sm-4 offset-sm-1">
<%= f.fields_for :categories do |nc| %>
<div class="form-group row">
<div class="col-sm-12">
<%= nc.text_field :name, class: 'form-control', placeholder: 'New category' %>
</div>
</div>
<% end %>
</div>