Rails 4: Dynamically change the Time method in a controller action - ruby-on-rails-4

I am trying to drill down some searches in my app using time intervals....posts in the last day, last week, last month. I am trying to be DRY and write a search controller method that will handle this for me. I am having probelms passing in the time variable. See the form below. #search_term is the search term and hidden becasue for this form as an example, all the client sees is a link saying "last 24 hours"
<%= form_tag time_searches_path do %>
<%= hidden_field_tag :search_task, #search_term %>
<%= hidden_field_tag :time, "24" %>
<%= hidden_field_tag :Klass, Micropost %>
<%= submit_tag "Last 24 hours", class: 'Criteria'%>
<% end %>
Then I have a helper method that is included in my search controller.....
def get_time_interval time
if time == "24"
#time_variable = 1.day.ago
elsif time == "week"
#time_variable = 1.week.ago
elsif time == "month"
#time_variable = 1.month.ago
end
end
Then I add the time_variable into my controller action
def search
model = params[:Klass]
klass = model.constantize
time = params[:time]
get_time_interval time
#search = Sunspot.search [klass] do
fulltext params[:search_task]
with(:created_at).greater_than(#time_variable)
end
end
Clearly this is wrong. I assuming i need some form of metaprogramming. I am new to rails to don't really know how to proceed.
Error I get is
undefined method `gsub' for nil:nilclass
And it highlights the line with the time variable in the controller

Related

Error: "param is missing or the value is empty: students"

I am new to rails. I can't understand what the error is and how to fix it.
Error is param is missing or the value is empty: students
form_for helper`
<%= form_for :students, :url=>{:action=>'create'} do |f| %>
Strong parameters
params.require(:students).permit(:s_name,:batch,:roll_no,:branch,:gender,:date_of_birth,:contact_no_1,:contact_no_2,:email,:spi_1,:spi_2,:spi_3,:spi_4,:spi_5,:spi_6,:spi_7,:cpi_7,:percent_10,:percent_12)
end
If you will inspect the params you'll find that your parameters are not in this form
{students: {'s_name': 'xyz', 'batch': 'cse'}}
It means the previous answer which was explained by #puneet is the best way to make CRUD's Try that way.
Try below code:
students controller
def new
#student = Student.new
end
def create
#student = Student.new(student_params)
#student.save
end
def student_params
params.require(:students).permit(:s_name,:batch,:roll_no,:branch,:gender,:date_of_birth,:contact_no_1,:contact_no_2,:email,:spi_1,:spi_2,:spi_3,:spi_4,:spi_5,:spi_6,:spi_7,:cpi_7,:percent_10,:percent_12)
end
view
<% form_for #student do |f| %>
...
<% end %>

Ruby on Rails, Datepicker search between two dates

I am a new ROR user trying to implement a DateTime picker to select dates for a search function.
My problem is that when I enter two dates (date from, and date to) in the DatePicker, I get inconsistent results from the search. Sometimes I get no results, and sometimes I get all the results. I am also using the bootstrap-datepicker-rails gem as well as the ransack gem.
This is what my view looks like
<div class="field">
<%= f.label :departure_date_gteq, "Departure Date Between" %>
<%= f.search_field :departure_date_gteq, "data-provide" => "datepicker" %>
<%= f.label :return_date_lteq, "and" %>
<%= f.search_field :return_date_lteq, "data-provide" => "datepicker" %>
</div>
The two database columns I am referencing are departure_date, and return_date. The date stored is datetime and looks like this,
departure_date
2016-08-07 00:00:00.000000
return_date
2016-08-14 00:00:00.000000
I enter 2016-08-06 and 2016-08-15 in the DatePickers and I am returned all the results.
Could my search form DatePicker be sending data that cannot be correctly compared to the DateTime in the database?
Am I using the 'gteq' and 'lteq' calls correctly?
EDIT #1
#Michael Gaskill, you are correct that the problem is the date formatting. When I enter a date manually, I get the correct search results. I just need to figure out how to correct the formatting before its passed to the controller.
Here is what my controller looks like.
class HomeController < ApplicationController
def index
#search = Sailing.search(params[:q])
#sailings = #search.result
... Other calls ...
end
end
Here is the full piece of code in my view that generates sailings content. Note that I'm using search_for_for which is part of the ransack gem.
<%= search_form_for #search, url: root_path, method: :post do |f| %>
<div class="field">
<%= f.label :cruise_ship_name_or_cruise_ship_company_or_destination_identifier_cont, "Cruise Ship Name" %>
<%= f.text_field :cruise_ship_name_or_cruise_ship_company_or_destination_identifier_cont %>
</div>
<div class="field">
<%= f.label :departure_date_gteq, "Departure Date Between" %>
<%= f.search_field :departure_date_gteq, "data-provide" => "datepicker" %>
<%= f.label :return_date_lteq, "and" %>
<%= f.search_field :return_date_lteq, "data-provide" => "datepicker" %>
</div>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
Thanks.
You need to convert the string-formatted dates entered in the form (either via the DatePicker or manually-entered) to Date or DateTime values. When you query the database, use this DateTime#strptime to convert:
MyTable.where(date_field_to_search: DateTime.strptime(date_value_from_ui, "%F %T")
You can check out the formats available as the second argument to strptime, using the instructions at DateTime:strftime. Note that strftime and strptime are used to convert back and forth between DateTime and formatted String values.
In your Sailing#search(params[:q]) example, you can either implement the solution in Sailing#search (if you have access to change that code) or prior to calling Sailing.search.
Here is how you might implement this in Sailing#search:
class Sailing
def search(args)
datetime = args[:date_field_to_search]
if datetime.kind_of?(String)
datetime = DateTime.strptime(datetime, "%F %T")
end
# other search functionality
end
end
or, prior to calling Sailing#search:
datetime = params[:q][:date_field_to_search]
if datetime.kind_of?(String)
datetime = DateTime.strptime(datetime, "%F %T")
end
Sailing.search(params[:q].merge({ date_field_to_search: datetime })

rails 4 ransack gem, undefined path error

I have rails 4 app with an Events model that I want to make searchable on a variety of fields using the Ransack gem.
my controller action:
def index
#search = Event.ransack(params[:q])
#events = #search.result(distinct: true)
end
my search form in index.html.erb:
<%= search_form_for #search do |f| %>
<%= f.text_field :name_cont, class: "radius-left expand", placeholder: "Event Name" %>
<% end %>
However, in loading the page, I get the following error:
ActionView::Template::Error (undefined method events_path' for #<#:0x007fc08b3fa838>): 1: Events 2: 3: <%= search_form_for #search do |f| %> 4: <%= f.text_field :name_cont, class: "radius-left expand", placeholder: "Event Name" %> 5: <% end %> 6: app/views/events/index.html.erb:3:in_app_views_events_index_html_erb___2056451196739971413_70232473324180'
when I rake routes, I get:
events_show GET /events/show(.:format) events#show
events_index GET /events/index(.:format) events#index
so i assume if I could get this form to point to events_index_path, it would work as expected.
what do I need to do to specify the correct path for the form?
Tbh i am not sure what i did to get this working. here is my controller index action now, which includes a distance/location search feature:
def index
if params[:within].present? && (params[:within].to_i > 0)
#search = Event.near(params[:location],params[:within]).search(params[:q])
else
#search = Event.search(params[:q])
end
#events = #search.result
end

Rails 4 search from "home page" to other models/controllers

UPDATE 4-6-2015:
Double checked here:
https://github.com/activerecord-hackery/ransack
to make sure I had everything right, aside from a few hiccups I think I do. I am not clear how or what automagic makes the f.submit whisk the user away to that model index with nothing in that model filled out, and the index action taking presidence (hence after doing a search takes me to the index view of the groups (what I am searching on) and shows everything from db as if the Group.all was called ignoring the search string (that I can see in the address bar) completely.
Really not sure what I am missing I am sure it something minusculey stupid on my part.
EDIT/UPDATE: So i got most of this working, the search screen is going to that controller. I am not sure what automagic is causing that, I thought my respond_to could trap and send back json so I could this with an ajax call and update the table that is in the main page. THEN if they click on that table it takes them to the edit form of that particular item (i.e. the edit of the correct model).
My visitor_controller.rb:
def index
#search = Group.ransack(name_cont: params[:q])
#groups = #search.result
respond_to do |format|
format.html
format.js
end
end
Adding the routes file too:
Rails.application.routes.draw do
resources :groups
get 'visitors', to: 'visitors#index'
root to: 'visitors#index'
end
So groups is a controller/model that I am trying to search on (one of many, will use the example in the answer to do many when I get the one just working first.)
So I am building an app, I found a "simple search" tutorial for rails 4:
http://www.stefanosioannou.com/rails-4-simple-search-form/
But I think that this assumes you to search from the view/model and all that of your controller. I.e.
I am in the groups view, I want to search my groups all through that controller.
Really what I am doing and finding so hard to do is have a welcome page, that has three search bars. Each bar searches a different model/view/controller.
The welcome page is called visitors and has its own controller, and view just no model.
So my visitors controller has this:
class VisitorsController < ApplicationController
def index
#groups = Group.search(params[:gsearch])
respond_to do |format|
format.html
format.js
end
end
end
I was just trying to get one search bar working for my Group model, so in my Visitors index.html.erb:
<div class="span12">
<h3>Welcome IPA of NM</h3>
<!-- search bar here -->
<% form_tag group_path, :method => 'get' do %>
<p>
<%= text_field_tag :gsearch, params[:search] %>
<%= submit_tag "Search Groups", :name => nil %>
</p>
<% end %>
</div>
This fails though as it says
No route matches {:action=>"show", :controller=>"groups"} missing required keys: [:id]
so here is my groups controller:
class GroupsController < ApplicationController
before_action :set_group, only: [:show, :edit, :update, :destroy]
def show
end
private
# Use callbacks to share common setup or constraints between actions.
def set_group
#group = Group.find(params[:id])
end
end
I am sure somehow the form code in the visitors index.html.erb is working with that group_path which means it is trying to do a show but has no ID yet when just starting? I really am lost, new to rails4 and not sure what I am missing here. I am guessing the convention is do all things from your model/view/controller not a cross views as I am trying to do here? So something I have to do extra to get around the convention or I am doing the whole thing wrong from the get go?
I would highly recommend Ransack for search queries in rails. You can view it here > https://github.com/activerecord-hackery/ransack and you can also watch an awesome rails cast by Ryan Bates over at http://railscasts.com/episodes/370-ransack
Ransack works across the board, you could even search all 3 models from the same form.
Using ransack, you would simply use:
<%= search_form_for #q do |f| %>
# Search if the models name field contains...
<%= f.label :name_cont %>
<%= f.search_field :name_cont %>
<%= f.submit %>
<% end %>
Then the search controller processes this into #results:
def index
#q = params[:q]
#search = Model.search(name_cont: #q)
#results = #search.result
end
Then you would loop through the results on your show/index page.
<% #results.each do |result| %>
<%= result.name
<% end %>
This would show all of your results on one search page. If you wanted to search multiple models, you can either have multiple forms assigning a different instance variable for each one eg: #q1 #q2 #q3 or, you could search them all from one model by using different instance variables for the search and results.eg
def index
#q = params[:q]
#firstsearch = User.search(username_cont: #q)
#secondsearch = Post.search(title_or_description_cont: #q)
#users = #firstsearch.result
#posts = #secondsearch.result
end
Remember to add the routes =)
get 'search', to: 'search#index'

Rails: How to store values dynamically or as cookie

May be the question will sound weird. But as I am doing it very first time, don't know what is it exactly called.
I have a search method with typeahead used in it on homepage of www.mealnut.com (do check a live demo). There are two entries, city and category. City shows data in typeahead array and on submit, gives the search result. Here is a code:
<%= form_tag search_path, :method => 'get' do %>
<%= text_field_tag 'search', nil, :placeholder =>"Enter your city ", :autocomplete => :off, :'data-provide' => "typeahead", :id=>"citysearch" %>
<%= select_tag :category, options_from_collection_for_select(#categories, "id", "category", params[:category]), html_options = { :prompt => 'Select a category'} %>
<%= submit_tag "Search"%>
<% end %>
And here is typeahead script:
$(document).ready(function(){
var cities = ["Bengaluru", "Pune", "New Delhi", "Delhi", "Mumbai"
$("input[data-provide='typeahead']").typeahead({source: cities});
});
And here is issue: when user clicks on back button to return on home page, city gets wiped out and category remains as selected. Here user should see city, he entered last time instead of blank field.
I think this happens cause typeahead just gives array and doesn't store value anywhere. I dont want to create separate table for array.
i found cookie might be the option. But dont know how to go with it as never tried cookie. Also, what is the best solution on this cookie or anything else? Has anybody done this?
Please help!
Update:
I used cookie for one city in controller. My home controller's index action is:
def index
#categories = Category.all
cookies[:search] = "Mumbai"
end
And modified index page form for search to:
<%= text_field_tag 'search', nil, :placeholder =>"#{cookies[:search]} ", :autocomplete => :off, :'data-provide' => "typeahead", :id=>"citysearch" %>
This shows city Mumbai on back button click. But i dont want city to be fixed. It should be user entered value. Can anyone tell how to do it?