Есть ли способ добавить новые значения в поле collection_select в форме в Rails 6? - PullRequest
1 голос
/ 26 февраля 2020

В моем приложении блога есть записи, и каждый пост может иметь теги. Когда пользователь находится в новой или редактируемой форме публикации, у него в настоящее время есть средства для выбора или отмены выбора тегов для связи с публикацией. Между моделями записей и тегов существует отношение многие ко многим, и я использую bootstrap, bootstrap_form и bootstrap -select. Это все работает, казалось бы, очень хорошо. Проблема в том, что когда пользователь назначает теги для своего сообщения, эти теги в настоящее время уже должны существовать (в противном случае ему придется прервать публикацию и go добавить теги ... плохой пользовательский опыт). Я пытаюсь придумать способ дать пользователю возможность создавать новые теги и / или выбирать уже существующие теги и применять их к сообщению, все в одной форме сообщения в поле collection_select, все одновременно.

По-видимому, я задаю неправильные вопросы в Google ... разве это не является распространенной потребностью, уже решена?

Я прошу указаний по предоставлению "добавить новый тег" функциональность для другого функционального поля collection_select. Как лучше go об этом?

Контроллер сообщений:

class PostsController < ApplicationController
  before_action :set_post, only: %i[edit update interim destroy]


  # GET /posts
  # GET /posts.json
  def index
    if user_signed_in? && current_user.admin_role
      if params[:tag]
        @posts = Post.tagged_with(params[:tag]).all.order('updated_at DESC').page params[:page]
      else
        @posts = Post.all.order('updated_at DESC').page params[:page]
      end
    else
      if params[:tag]
        @posts = Post.tagged_with(params[:tag]).where(published: true).order('updated_at DESC').page params[:page]
      else
        @posts = Post.where(published: true).order('updated_at DESC').page params[:page]
      end
    end

  end


  # GET /posts/new
  def new
    @post = current_user.posts.build
    @categories = Category.pluck(:name, :id)
  end

  # GET /posts/1/edit
  def edit
    @categories = Category.pluck(:name, :id)
    @cat = @post.category_id
  end

  # POST /posts
  # POST /posts.json
  def create
    @post = current_user.posts.create(post_params)

    respond_to do |format|
      if @post.save
        if params[:interim]
          format.html { redirect_to edit_post_path(@post), notice: 'Post was successfully created.' }
          format.json { redirect_to edit_post_path(@post), status: :created, location: @post, notice: 'Post was successfully created.' }
        elsif params[:complete]
          format.html { redirect_to @post, notice: 'Post was successfully created.' }
          format.json { render :show, status: :created, location: @post }
        end
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /posts/1
  # PATCH/PUT /posts/1.json
  def update
    respond_to do |format|
      if @post.update(post_params)
        if params[:interim]
          format.html { redirect_to edit_post_path(@post), notice: 'Post was successfully updated.' }
          format.json { redirect_to edit_post_path(@post), status: :ok, location: @post, notice: 'Post was successfully updated.' }
        elsif params[:complete]
          format.html { redirect_to @post, notice: 'Post was successfully updated.' }
          format.json { render :show, status: :ok, location: @post }
        end
      else
        format.html { render :edit }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /posts/1
  # DELETE /posts/1.json
  def destroy
    @post.destroy
    respond_to do |format|
      format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private


  def set_post
    @post = Post.find(params[:id])
  end


  def post_params
    params.require(:post).permit(:title, :content, :user_id, :published, :category_id, :tag_list, :tag, { tag_ids: [] }, :tag_ids,
      comment_attributes: [:id, :title, :user_id, :content, :post_id, :parent_id, :ancestry, :commentable, :commentable_id, :commentable_type])
  end
end

Нет контроллера тегов (пока не требуется)

Модель сообщения:

class Post < ApplicationRecord

    has_many :taggings
    has_many :tags, through: :taggings
    has_rich_text :content

    include PgSearch::Model
    multisearchable :against => [:title, :content]

    def self.published(post)
      post.published
    end

    def self.tagged_with(name)
      Tag.find_by!(name: name).posts
    end

    def self.tag_counts
      Tag.select('tags.*, count(taggings.tag_id) as count').joins(:taggings).group('taggings.tag_id')
    end

    def tag_list
      tags.map(&:name).join(', ')
    end

    def tag_list=(names)
      self.tags = names.split(',').map do |n|
        Tag.where(name: n.strip).first_or_create!
      end
    end

end

Модель тега:

class Tag < ApplicationRecord
  has_many :taggings
  has_many :posts, through: :taggings
end

Модель тегирования:

class Tagging < ApplicationRecord
  belongs_to :tag
  belongs_to :post
end

Частичная форма публикации (фактические новые и редактируемые представления ничего не делают, кроме как визуализируют эту форму):

<%= bootstrap_form_for @post, local: true, html: { class: 'form-horizontal' } do |f| %>

  <%= f.text_field :title %>

  <%= f.rich_text_area :content, control_class: 'trix-content-edit' %>

  <%= f.collection_select :category_id, Category.all, :id, :name %>

  <%= f.form_group :published, label: { text: "Publication Status" } do %>
    <%= f.radio_button :published, true, label: "Published" %>
    <%= f.radio_button :published, false, label: "Draft" %>
  <% end %>

  <%= f.collection_select :tag_ids, Tag.order(:name), :id, :name, {label: 'Tags', include_blank: true}, {class: 'selectpicker show-tick', multiple: 'multiple', title: 'Make your selection...', 'data-live-search': 'true', 'data-actions-box': 'true'} %>

  <br><br>
  <%= f.submit "Save and Resume Editing", name: "interim", class: "btn btn-primary" %>
  <%= f.submit "Save and Quit", name: "complete", class: "btn btn-primary" %>
  <br><br>

<% end %>

В настоящее время нет форм для тега.

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