Reputation: 5854
parent.rb
class Parent
include Mongoid::Document
field :name, type: String
field :hobby, type: String
field :born, type: Date
embeds_many :children
accepts_nested_attributes_for :children
end
children.rb
class Child
include Mongoid::Document
field :hobby, type: String
field :name, type: String
field :born, type: Date
embedded_in :parent
end
parents_controller.rb
class ParentsController < ApplicationController
before_action :set_parent, only: [:show, :edit, :update, :destroy]
# GET /parents
# GET /parents.json
def index
@parents = Parent.all
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
Parents' index.html.erb:
<h1>Listing parents</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Born</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% @parents.each do |parent| %>
<tr>
<td><%= parent.name %></td>
<td><%= parent.born %></td>
<td><%= link_to 'Show', parent %></td>
<td><%= link_to 'Edit', edit_parent_path(parent) %></td>
<td><%= link_to 'Destroy', parent, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Parent', new_parent_path %>
I want to implement a search feature to search not only in the main document but in the nested as well. Search not only in text fields, but also with date ranges. Can anyone point me any resource (tutorial) regarding this? I couldn't find anything like Ryan's Simple Search railscast. I'd very obliged if someone could show me how I will have to modify my controllers and index.html.erb files.
There's also a Durran's page related to search in the github https://github.com/mongoid/mongoid/blob/master/lib/mongoid/contextual/text_search.rb. But frankly speaking it didn't give any clue to solve my issue.
Upvotes: 0
Views: 832
Reputation: 5854
Thanks to @Pierre-Louis Gottfrois for advice that helped me do some further research.
I became able to search on two fields (name and hobby) as follows.
I've added onto 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 %>
Then in the parent.rb model I changed taking into account @Pierre-Louis Gottfrois's advice :
def self.search(search)
if search
any_of({name: search}, {hobby: search})
end
end
products_controller.rb changed:
def index
if params[:search].empty?
@parents = Parent.all
else
@parents = Parent.search(params[:search])
end
end
There're 3 problems still exist and I thought it would be better split them in different posts:
Upvotes: 1
Reputation: 17631
You'll want for example to have your index
method taking a search
param
def index
@parents = if params[:search]
Parent.where(name: params[:search])
else
Parent.all
end
end
This is the basic idea. You may consider having a class method for doing more complex search (using born
attributes for example).
def index
if params[:search]
@parents = Parent.search_for(params[:search])
else
@parents = Parent.all
end
end
In your model:
class Parent
def search_for(criterias)
# Logic regarding criterias selection should go here.
# Very basic idea bellow
Parent.where(name: criterias[:name], born: criterias[:born])
end
end
In your view:
// First case
<%= text_field_tag :search, '' %>
// Second case
<%= text_field_tag 'search[name]', '' %>
<%= text_field_tag 'search[born]', '' %>
Upvotes: 2