Sunspot search doesn't work - ruby-on-rails

I'm trying to make an search option in my site, but it won't show results after an search query.
I have followed this tutorial: http://collectiveidea.com/blog/archives/2011/03/08/full-text-searching-with-solr-and-sunspot/
My routes.rb:
resources :users do
collection do
get :search
end
member do
get :following, :followers
end
end
My index.html.erb
<table>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New User', new_user_path %>
My model user.rb
searchable do
text :name
end
And my user controller
def index
#users = User.paginate(page: params[:page])
end
def search
#users = User.search do
keywords params[:query]
end.results
respond_to do |format|
format.html { render :action => "index" }
end
end
What am i doing wrong?

Related

ActiveRecord::RecordNotFound in StoriesController#edit

I have correctly defined the params in my controller. It also says No route matches {:action=>"edit", :controller=>"stories", :id=>nil} missing required keys: [:id]'.
However didn't I define it to find the 'id' in the edit method below in my controller? Also, I don't understand why my destroy method isn't working either :/
class StoriesController < ApplicationController
before_action only: [:destroy, :show, :edit, :update]
def index
#stories = Story.order('created_at DESC')
end
def new
#story = current_user.stories.build
end
def create
#story = current_user.stories.build(story_params)
if #story.save
flash[:success] = "Your beautiful story has been added!"
redirect_to root_path
else
render 'new'
end
end
def edit
#story = Story.find(params[:id])
end
def update
if #story.update.attributes(story_params)
flash[:success] = "More knowledge, more wisdom"
redirect_to root_path
else
render 'edit'
end
end
def destroy
if #story.destroy
flash[:success] = "I think you should have more confidence in your storytelling"
else
flash[:error] = "Can't delete this story, sorry"
end
end
def show
#stories = Story.all
end
private
def story_params
params.require(:story).permit(:name, :description)
end
end
Index.html.erb:
<p id="notice"><%= notice %></p>
<h1>This is a list of posts</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>User</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #stories.each do |story| %>
<tr>
<td><%= story.name %></td>
<td><%= story.description %></td>
<td><%= story.user.email %></td>
<td><%= link_to 'Show', story %></td>
<% if user_signed_in? %>
<td><%= link_to 'Edit', edit_story_path(#story) %></td>
<td><%= link_to 'Destroy', story, method: :delete, data: { confirm: 'Are you sure?'} %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'New Story', new_story_path %>
Routes.rb:
Rails.application.routes.draw do
resources :stories
devise_for :users
root to: 'stories#index'
end
rake routes:
Prefix Verb URI Pattern Controller#Action
stories GET /stories(.:format) stories#index
POST /stories(.:format) stories#create
new_story GET /stories/new(.:format) stories#new
edit_story GET /stories/:id/edit(.:format) stories#edit
story GET /stories/:id(.:format) stories#show
PATCH /stories/:id(.:format) stories#update
PUT /stories/:id(.:format) stories#update
DELETE /stories/:id(.:format) stories#destroy
In your view,
<td><%= link_to 'Edit', edit_story_path(#story) %></td>
Should be,
<td><%= link_to 'Edit', edit_story_path(story) %></td>
Because, your loop is,
You should be having story variable inside loop because you have taken |story| inside the parameters as |story|
So, you form will be.
<% #stories.each do |story| %>
<tr>
<td><%= story.name %></td>
<td><%= story.description %></td>
<td><%= story.user.email %></td>
<td><%= link_to 'Show', story %></td>
<% if user_signed_in? %>
<td><%= link_to 'Edit', edit_story_path(#story) %></td>
<td><%= link_to 'Destroy', story_path(story),method: :delete,data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
Now, the delete link should be like this,
<td><%= link_to 'Destroy', story_path(story),method: :delete,data: { confirm: 'Are you sure?' } %></td>

How can I create checkboxes, set checkbox values, sum them up to one task model value and sort tasks according to that value?

I'm making a to-do list with Rails. I want to have two checkboxes for every task ("Important" and "Urgent"). I want to sort those tasks according to two criteria.
First criteria are the checkboxes and the second criteria should be the time where the task has been created or updated. So with the first criteria there are 4 priorities which the tasks should be sorted:
Task (important and urgent checbox checked)
Task (important checkbox checked, urgent is not checked)
Task (urgent checkbox is checked, important is not checked)
Task (no checboxes are checked)
If there are multiple tasks with the same priority those should be sorted descending by the second criteria but within the first criteria.
I would create a migration to add an integer to the task model and then set the checkboxes to the values: "important = 2" and "urgent = 1" (unchecked value = 0). Those checkbox values should be summed up and linked to the integer in the task model and then I would sort them in the task view.
Questions:
How can I make checkboxes, set checkbox values and sum them up to one task model value?
How can I sort the tasks according to the summed up value?
How can I sort the tasks by the created/updated time as second criteria?
index.html.erb (task view)
<h1>To Do</h1>
<table>
<thead>
<th>Content</th>
<th>State</th>
<th></th>
<th></th>
<th></th>
<th></th>
</thead>
<tbody>
<% #to_do.each do |task| %>
<tr>
<td><%= task.content %></td>
<td><%= task.state %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task_path(task), method: :delete, data: { confirm: "Are you sure to delete this task?" } %></td>
<td><%= link_to 'Mark as Doing', change_task_path(task, state: "doing"), method: :put %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<h1>Doing</h1>
<table>
<thead>
<th>Content</th>
<th>State</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</thead>
<tbody>
<% #doing.each do |task| %>
<tr>
<td><%= task.content %></td>
<td><%= task.state %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task_path(task), method: :delete, data: { confirm: "Are you sure to delete this task?" } %></td>
<td><%= link_to 'Mark as To Do', change_task_path(task, state: "to_do"), method: :put %></td>
<td><%= link_to 'Mark as Done', change_task_path(task, state: "done"), method: :put %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<h1>Done</h1>
<table>
<thead>
<th>Content</th>
<th>State</th>
<th></th>
<th></th>
<th></th>
<th></th>
</thead>
<tbody>
<% #done.each do |task| %>
<tr>
<td><%= task.content %></td>
<td><%= task.state %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task_path(task), method: :delete, data: { confirm: "Are you sure to delete this task?" } %></td>
<td><%= link_to 'Mark as Doing', change_task_path(task, state: "doing"), method: :put %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Task', new_task_path %>
new.html.erb (task new view)
<h1>New Task</h1>
<%= form_for(#task) do |f| %>
<%= f.text_field :content, placeholder: "Content", class: "formfield" %>
<%= f.submit "Save Content", class: "form_button" %>
<% end %>
<%= link_to 'Back', tasks_path %>
tasks_controller.rb
class TasksController < ApplicationController
before_action :logged_in_user
before_action :set_task, only: [:show, :edit, :update, :destroy, :change]
def index
#to_do = current_user.tasks.where(state: "to_do")
#doing = current_user.tasks.where(state: "doing")
#done = current_user.tasks.where(state: "done")
end
def show
end
def new
#task = Task.new
end
def edit
end
def create
#task = current_user.tasks.new(task_params)
if #task.save
flash[:success] = "You successfully created a Task!"
redirect_to tasks_path
else
render 'new_task_path'
end
end
def update
#task.update(task_params)
if #task.save
flash[:success] = "You successfully updated a Task!"
redirect_to tasks_path
else
render 'edit_task_path'
end
end
def destroy
#task.destroy
flash[:success] = "You successfully deleted a Task!"
redirect_to tasks_path
end
def change
#task.update_attributes(state: params[:state])
flash[:success] = "You successfully changed the State!"
redirect_to tasks_path
end
private
def set_task
#task = Task.find(params[:id])
end
def task_params
params.require(:task).permit(:content, :state)
end
end
Solution by OP.
task.rb
class Task < ActiveRecord::Base
belongs_to :user
scope :important, -> { where(important: true) }
scope :urgent, -> { where(urgent: true) }
default_scope { order(:important => :desc, :urgent => :desc, :updated_at => :desc, :created_at => :desc) }
end
new.html.erb
<h1>New Task</h1>
<%= form_for(#task) do |f| %>
<%= f.text_field :content, placeholder: "Content", class: "formfield" %>
<strong>Important:</strong>
<%= f.check_box :important %>
<strong>Urgent:</strong>
<%= f.check_box :urgent %>
<%= f.submit "Save Content", class: "form_button" %>
<% end %>
<%= link_to 'Back', tasks_path %>
Q1: How can I make checkboxes, set checkbox values and sum them up to one task model value?
I don't think that summing the checkbox values to one 'task model value' is the best solution. I would add both an Urgent and an Important column to your Task model. This is far more scalable in the long run and easier to work with generally. Then it's just a case using the Rails check_box_tag helper. http://apidock.com/rails/ActionView/Helpers/FormTagHelper/check_box_tag
Q2: How can I sort the tasks according to the summed up value?
If you have separate columns/attributes for the important and urgent you can create scopes on your task model to sort as you wish.
scope :important, -> { where(important: true) }
scope :urgent, -> { where(urgent: true) }
You can then chain your named scopes as you require.
Task.important.urgent
or maybe you can also specify a recent scope:
scope :recent, -> { order("posts.updated_at DESC") }
and then call:
Task.important.recent
which would run the following SQL query:
# SELECT "tasks".* FROM "tasks" WHERE "tasks"."important" = 'true'
# ORDER BY tasks.updated_at DESC
Q3: How can I sort the tasks by the created/updated time as second criteria?
The above query sort of addresses this but you could also use:
Task.order(important: :asc, created_at: :desc)
Hope some of this is helpful.

NoMethodError in MicropostsController#index

I cannot figure this out-
NoMethodError in MicropostsController#index
and
I have searched the web and cannot seem to make the right change. I am doing Michael Hartl's Rails Tutorial and I am in ch 2 where we do microposts.
Here's index.html.erb
Listing Microposts
<table>
<thead>
<tr>
<th>Content</th>
<th>User</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #microposts.each do |micropost| %>
<tr>
<td><%= micropost.content %></td>
<td><%= micropost.user_id %></td>
<td><%= link_to 'Show', micropost %></td>
<td><%= link_to 'Edit', edit_micropost_path(micropost) %></td>
<td><%= link_to 'Destroy', micropost, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Micropost', new_micropost_path %>
and
Microposts Controller
Class MicropostsController < ApplicationController
def index
end
def show
end
def new
end
def edit
end
def create
end
def update
end
def destroy
end
end
You are getting this error because there is no microposts instance variable in index action, in index action you should set #microposts like this:
def index
#microposts = Micropost.all
end

Ajax edit page in index

I have this page Index page:
<h1>Listing users</h1>
<table border="1">
<tr>
<th>Name</th>
<th>Description</th>
<th>Who</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.description %></td>
<td><%= user.who %></td>
<%= render 'users/form' %>
<td><%= link_to 'Show', user %></td>
<td><%= link_to 'Edit', edit_user_path(user) %></td>
<td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New User', new_user_path %>
Scaffold controller
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
I need to edit user in index page, not to go url /users/2/edit, stay on users page.
How I do this in Ajax?
Add remote:true to the Edit line in order to make an ajax call:
<td><%= link_to 'Edit', edit_user_path(user), remote:true %></td>
Also, add an edit.js.erb file (a javascript file with embedded ruby) in which you do all the javascript actions to be executed after the Edit. That edit.js.erb file is generated when the edit method is done. This is where you write all the changes to the javascript code which affect the current page (the page will not be re-rendered).
Additionally, add the following to the edit method:
respond_to do |format|
format.js
end

ruby printing database content

I am new in Ruby.
I have to render the database structure, using tutorial i found suitable code:
File index.html.erb:
<h1>Listing tasks</h1>
<table>
<tr>
<th>Title</th>
<th>Content</th>
<th>Date From</th>
<th>Date To</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.content %></td>
<td><%= task.datefrom %></td>
<td><%= task.dateto %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, :method => :delete, :data => { :confirm => 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Now i want to group tasks by 'date from' value, probably it means that in index.html.erb i should print only dates, and clicking on the date i should call another html file that will render tasks by chosen date.
this can be like
File index.html.erb:
<h1>Listing dates</h1>
<table>
<tr>
<th>Date From</th>
<% #tasks.each do |task| %>
<tr>
<td><%= !!! IF DATE NOT PRINTED THEN PTINT IT task.datefrom %></td>
<td><%= link_to 'Edit', edit_date_path(task, date) %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Where edit_date_path(task, date) should refer me to the index_date.html.erb, where i can get selected date and print tasks according to selected date.
Maybe i can get suggestion, it will be much easier is fomebody can help me with that, as task should not be very difficult, but otherwise i can waste quite a lot of time googling.
Thanks,
Urmas.
Editing the question.
This helped a little. what i did now, i changed index.html.erb to
<h1>Listing dates</h1>
<table>
<tr>
<th>Date To</th>
<th></th>
</tr>
<% dates = Array.new %>
<% #tasks.each do |task| %>
<% if ( !dates.include?(task.dateto.strftime("%m.%d.%Y")) ) then
dates.push task.dateto.strftime("%m.%d.%Y")
%>
<tr>
<td><%= task.datefrom.strftime("%m.%d.%Y") %></td>
<td><%= link_to 'Show Date', {:action => "index", :date => task.dateto} %></td> <-- This does not work
</tr>
<%
end
%>
<% end %>
</table>
<br />
<%= link_to 'New Task', new_task_path %>
Where 'Show Date' link link should be made to show_date.html.erb, where is correct code for showing records when input date is passed.
I had added in controller also method
def show_date
#tasks = Task.find(params[:dateto])
#dateto = :dateto
respond_to do |format|
format.html # showdate.html.erb
format.json { render :json => #tasks }
end
end
that can be used in the not working link, to pass data to the 'Show Date' (show_date.html.erb), but i get errors all the time. The problem is with correct calling off the show_date.html.erb, code i will be able to write myself :)
Urmas
in Tasks controller:
add a method
def index_date
#tasks = Task.all
end
and create a index_date.html.erb write
<% #tasks.each do |task| %>
<tr> <td><%= task.datefrom %></td>
<td><%= link_to 'Edit', {:action => "index", :date => task.datefrom} %></td>
</tr>
<%end%>
and in the index method in the controller change
#tasks = Task.all to
#tasks = Task.find_all_by_datefrom(#{params[:date])
This will list the tasks that match the date selected and everything will be similar as it is now thereafter.
Found the solution.
It were necessary to add to routes.rb
resources :tasks do
member do
get 'showdate'
end
get "home/index"
end
add corresponding controller processing
def showdate
#task = Task.find(params[:id])
#tasks = Task.find(:all)
respond_to do |format|
format.html # showdate.html.erb
format.json { render :json => #tasks }
end
end
and to call it using (index.html.erb)
<td><%= link_to 'Show Date', showdate_path(task.id) %></td>
All further processing is already in showdate.html.erb.
Hope this helps somebody.
I AM THE BEST!!!! xD

Resources