首页 > 解决方案 > 使用 has_scope gem Rails 显示活动过滤器

问题描述

我有一个 Entry 模型,它通过 entry_courses 拥有多个课程(通过关联拥有多个课程)。我已经在我的 entry.rb (模型)中设置了我的范围

scope :by_courses, -> (ids_ary) {
  joins(entry_courses: :course).where("courses.id" => ids_ary)
}

使用它,我可以使用 URL http://localhost:3000/entries?by_courses[]=5进行过滤

这会使用 过滤正确的条目course_id = 5

所以,我的问题是,当该参数在 URL 中传递时,如何在 index.html.erb 视图的顶部显示活动过滤器(课程名称)?

模型

class Entry < ApplicationRecord
    mount_uploader :attachment, AttachmentUploader

    has_many :entry_topics
    has_many :topics, through: :entry_topics

    has_many :entry_categories
    has_many :categories, through: :entry_categories

    has_many :entry_courses
    has_many :courses, through: :entry_courses



    belongs_to :user
    scope :by_categories, ->(ids_ary) { joins(entry_categories: :category).where("categories.id" => ids_ary) }
    scope :by_topics, ->(ids_ary) { joins(entry_topics: :topic).where("topics.id" => ids_ary) }
    scope :by_level, -> level { where(:level => level) }
    scope :by_courses, -> (ids_ary) { joins(entry_courses: :course).where("courses.id" => ids_ary) }

end

控制器

class EntriesController < ApplicationController
  before_action :set_entry, only: [:show, :edit, :update, :destroy]
  before_action :set_variables, only: [:new, :create, :show, :edit, :update, :index]
  before_action :authenticate_user!, only: [:new, :create, :edit, :update]
  before_action :user_is_current_user, only: [:edit, :update, :destroy]
  has_scope :by_categories, type: :array
  has_scope :by_level, type: :array
  has_scope :by_topics, type: :array
  has_scope :by_courses, type: :array


  # GET /entries
  # GET /entries.json
  def index
 @entries = if params[:term]
    Entry.where('title ILIKE ?', "%#{params[:term]}%")
  else    
    @entries = apply_scopes(Entry.order(:created_at => 'DESC'))
  end

  end



  # GET /entries/1
  # GET /entries/1.json
  def show
  end

  # GET /entries/new
  def new
    @entry = Entry.new(:user => @current_user)
  end

  # GET /entries/1/edit
  def edit

  end

  # POST /entries
  # POST /entries.json
  def create

    @entry = Entry.new(entry_params)
    @entry.user_id = current_user.id

    respond_to do |format|
      if @entry.save

        format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
        format.json { render :show, status: :created, location: @entry }

      else
        format.html { render :new }
        format.json { render json: @entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /entries/1
  # PATCH/PUT /entries/1.json
  def update
   user = User.find_by_id(@entry.user_id)
   entry = @entry
    respond_to do |format|
      if @entry.update(entry_params)
        format.html { redirect_to @entry, notice: 'Entry was successfully updated.' }
        format.json { render :show, status: :ok, location: @entry }
      else
        format.html { render :edit }
        format.json { render json: @entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /entries/1
  # DELETE /entries/1.json
  def destroy
    @entry.destroy
    respond_to do |format|
      format.html { redirect_to entries_url, notice: 'Entry was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_entry
      @entry = Entry.find(params[:id])

    end
    def set_variables
      @categories = Category.all
      @topics = Topic.all
      @courses = Course.all

    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def entry_params
      params.require(:entry).permit({topic_ids: []}, {category_ids: []}, {course_ids: []}, :description, :category_id, :title, :entry_type,:entry_type_other, :genre, :level, :course,  :attachment, :remove_attachment, :entry_id, :user, :user_id, :id, :url_link, :term)
    end
    def user_is_current_user
    unless current_user == @entry.user or current_user.admin?
      redirect_to(root_url, alert: "Sorry! You can't edit this resource since you didn't create it.") and return
    end
  end
end

标签: ruby-on-railsrubyfilterruby-on-rails-5has-scope

解决方案


在您的视图中使用将返回或类似current_scopes的哈希值。{by_courses: 5}

如何显示活动过滤器(课程名称)

在 application_helper.rb

def entries_name
  scope = current_scope.first 
  model = entries_scope_map[scope[0]]
  model.find(scope[1][0]).name
end 

def entries_scope_map
  {by_courses: Course}
end

在您看来(或类似的):

<%= entries_name %> 

推荐阅读