Ruby on Rails: добавление новой категории в форму сообщения в блоге, ассоциаций «многие ко многим» и вложенных форм. - PullRequest
0 голосов
/ 16 июня 2020

Я создаю блог и столкнулся с проблемой при добавлении категорий. Я реализовал два способа добавления новых категорий: отдельная форма и вложенная форма внутри сообщения. Все существующие категории отображаются с флажками под формой публикации, а также есть поле для добавления новой категории в форму публикации. Если я выберу одну категорию и создаю новую одновременно - обе записи попадут в базу данных. Но когда я редактирую сообщение и удаляю или меняю категории, текстовое поле, предназначенное для вставки нового имени категории, содержит ранее примененное имя категории (или несколько полей с именами): вот как это выглядит

Как сделать так, чтобы текстовые поля не отображали существующие категории?

А также: я все еще могу удалить категории, удалив весь текст из полей и сняв флажки в форме редактирования. Изменения сохраняются, а категории удаляются, но я вижу проблему «Недопустимый параметр:: 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>

1 Ответ

0 голосов
/ 18 июня 2020

Вам нужно добавить id в параметры статьи

def article_params params.require(:article).permit( :id, :title, :description, categories_attributes [ :id, :name, :destroy ], category_ids: [] ) end

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...