how to ignore case-sensitiveness and include neste

2019-08-08 16:29发布

问题:

parent.rb

class Parent
  include Mongoid::Document

  field :name, type: String
  field :hobby, type: String
  field :born, type: Date

  has_many :children
  accepts_nested_attributes_for :children

  def self.search(search)
    if search
        any_of({name: search}, {hobby: search})
    end
  end
end

child.rb:

class Child
  include Mongoid::Document
  field :name, type: String
  field :hobby, type: String
  field :born, type: Date

  belongs_to :parent
end

parents_controller.rb

class ParentsController < ApplicationController
  before_action :set_parent, only: [:show, :edit, :update, :destroy]

  # GET /parents
  # GET /parents.json
  def index
    if params[:search].empty?
      @parents = Parent.all
    else
      @parents = Parent.search(params[:search])
    end
  end

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

  # GET /parents/new
  def new
    @parent = Parent.new
  end

  # GET /parents/1/edit
  def edit
  end

  # POST /parents
  # POST /parents.json
  def create
    @parent = Parent.new(parent_params)

    respond_to do |format|
      if @parent.save
        format.html { redirect_to @parent, notice: 'Parent was successfully created.' }
        format.json { render action: 'show', status: :created, location: @parent }
      else
        format.html { render action: 'new' }
        format.json { render json: @parent.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /parents/1
  # PATCH/PUT /parents/1.json
  def update
    respond_to do |format|
      if @parent.update_attributes(parent_params)
        format.html { redirect_to @parent, notice: 'Parent was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @parent.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /parents/1
  # DELETE /parents/1.json
  def destroy
    @parent.destroy
    respond_to do |format|
      format.html { redirect_to parents_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_parent
      @parent = Parent.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def parent_params
      params.require(:parent).permit(:name, :hobby, :born)
    end
end

search tag in the product's index.html.erb

<%= form_tag parents_path, :method => 'get' do %>
<p>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag "Search", :name => nil %>
</p>
<% end %>

Questions:

  1. When I have 2 names: Alex and Alex Jr., and when I search for "Alex", it's giving me only one result. But I want "Alex Jr" also to be as a search result.
  2. My search is case-sensitive. I'd like to ignore this.
  3. I want to be able to search not only in the main document, but also in the nested ones in all levels. In this case, I have main document as a model parent.rb and nested one called child.rb. So, for example, when I search for name, I will want to search not only parent's name but also in his child.
  4. I would like to add an ability to search by specifying date range. For example, to find all records who was born from A date to B date.

回答1:

You can write:

def self.search(search)
  if search
    any_of({name: /#{search}/i}, {hobby: /#{search}/i})
  end
end

That will give you all objects that include this value, with ignoring case-sensitive.

About adding search by date range. Send to your controller an additional value - for example ~ search_to.

def index
  @parents = if params[:search]
     Parent.search(params[:search], params[:search_to]) # when searching name/hobby, params[:search_to] will be nil
   else
     Parent.all
  end
end

Your search function:

def self.search(search, search_to)
  if search && search_to
    where(:born => {'$gte' => Date.parse(search),'$lt' => Date.parse(search_to)})
  elsif search
    any_of({name: /#{search}/i}, {hobby: /#{search}/i})       
  end
end

Question 3 - I don't understand what is your problem.