ruby printing database content - ruby-on-rails

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

Related

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.

Filter paginated posts by date introduced by user (Rails)

I have the post_controller with index method like this:
def index
#posts = Post.paginate(:page => params[:page], :per_page => 3)
end
and in app / views / posts / index.html.erb i have:
.
.
.
<table>
<tr>
<th>User</th>
<th>Post</th>
<th>Date</th>
<th colspan="3"></th>
</tr>
<% #posts.each do |post| %>
<tr>
<td><%= post.user.id %></td>
<td><%= post.text %></td>
<td><%= post.created_at %></td>
<td><%= link_to 'Show', post_path(post) %></td>
<% if can? :update, post %>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<% end %>
<% if can? :destroy, post %>
<td><%= link_to 'Destroy', post_path(post),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
<%= will_paginate #posts %>
</table>
So i want a field in this view, where an user can input a date and the view shows all posts wich were created on that date onwards. (Posts date > date_by_user). I tried with "where" method but i couldnt. I dont want to use any gem. So, what is the best and simple way to do that?
You can search records in index method like below.
date_to_search = Date.parse('2015/1/1')
Post.where(
'created_at>=? and created_at<=?',
date_to_search.beginning_of_day
)
created_at is saved as UTC in rails, so you need to specify datetime. Not only date, to get correct data in your local time.

Simple range search in Rails

I'm new to ROR and I'm trying to implement a simple search which should allow a user to search for hikes that match a certain range of difficulty. The form is properly displayed and I do not get any error messages, the problem is that no search results are dispayed.
I've been trying to solve this for a whole day now, so any help is extremely appreciated!
Index.html.erb
<%= form_tag wanderungens_path, :method => 'get' do %>
<p>
<%= number_field_tag ':search[dauer_von]', #search.dauer_von %>
<%= number_field_tag ':search[dauer_bis]', #search.dauer_bis %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
Wanderungens_controller.rb
def index
#search = WanderungenSearch.new(params[:search])
#wanderungens = #search.scope
end
wanderungen_search.rb
class WanderungenSearch
attr_reader :dauer_von, :dauer_bis
def initialize(params)
params ||= {}
#dauer_von = params[:dauer_von]
#dauer_bis = params[:dauer_bis]
end
def scope
Wanderungen.where('zeitdauer BETWEEN ? AND ?', #dauer_von, #dauer_bis)
end
I followed this tutorial: https://www.youtube.com/watch?v=Ri1YNjl1_hA
I'm on Rails 4.0.0 and Ruby 2.0.0
Update: This is the code where #Wanderungens is displayed:
<table>
<thead>
<tr>
<th>Description</th>
<th>User</th>
<th>Schwierigkeitsgrad</th>
<th>Zeitdauer</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #wanderungens.each do |wanderungen| %>
<tr>
<td><%= wanderungen.description %></td>
<td><%= wanderungen.user.email if wanderungen.user %></td>
<td><%= wanderungen.schwierigkeitsgrad.description if wanderungen.schwierigkeitsgrad %></td>
<td><%= wanderungen.zeitdauer if wanderungen.zeitdauer %></td>
<td><%= link_to 'Show', wanderungen %></td>
<td><%= link_to 'Edit', edit_wanderungen_path(wanderungen) %></td>
<td><%= link_to 'Destroy', wanderungen, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
If I search from 1 to 2, the following request is generated:
http://localhost:3000/wanderungens?utf8=%E2%9C%93&%3Asearch[dauer_von]=1&%3Asearch[dauer_bis]=2

Edit Multiple (reference Railscasts Episode #165)

I'm following Railscasts Episode #165 Edit Multiple but having issue where when I go to the product index page it is not showing my list of products. I'm getting only the header and the link to new product. Any idea what I did wrong?
By the way I'm using rails 3.2.3
Thank you.
routes.rb
resources :products do
collection do
post :edit_multiple
put :update_multiple
end
end
resources :categories
index.html.erb
<h1>Listing products</h1>
<% form_tag edit_multiple_products_path do %>
<table>
<tr>
<th></th>
<th>Name</th>
<th>Category</th>
<th>Price</th>
</tr>
<% for product in #products %>
<tr>
<td><%= check_box_tag "product_ids[]", product.id %></td>
<td><%= product.name %></td>
<td><%= product.category.name %></td>
<td><%= product.price %></td>
<td><%= link_to "Edit", edit_product_path(product) %></td>
<td><%= link_to "Destroy", product, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<%= submit_tag "Edit Checked" %>
<% end %>
<p><%= link_to "New Product", new_product_path %></p>
You need <%= form_tag ... instead of <% form_tag .... Without the = the return value (i.e. your form) is discarded rather than added to the output.
I think this is typo.
you forgot to use "=" You should do <%= form_tag edit_multiple_products_path do %>

Rails 3 task scopes?

I am working on a simple rails 3 todo application and I am trying to filter the app by completed tasks and none completed task but whenever I try calling a scope I get the error message.
undefined method `completed' for #<Array:0x007fe8420d0e58>
task.rb
scope :completed , where(:completed => true)
scope :incomplete , where(:finished => false)
index.html.erb
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Finished</th>
<th>User</th>
</tr>
<% #tasks.each do |task| %>
<tr>
<td><%= task.name %><%= button_to "complete", complete_task_path(task.id)%></td>
<td><%= task.description %></td>
<td><%= task.finished %></td>
<td><%= task.user_id %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
</table>
<%= content_tag :h2, "Stuff Ive done" %>
<table>
<tr>
<th>Name</th>
</tr>
<% #tasks.completed.each do |task| %>
<tr>
<td><%= task.name %></td>
</tr>
<% end %>
</table>
task_controller.rb
def complete
#task = Task.find(params[:task_id])
#task.completed = true
#task.save
redirect_to task_path
end
routes.rb
match "tasks/:id/complete" => "task#complete", :as => :complete_task
Any reasons why rails is giving me this error?
Just by looking at your view (index.html.erb), in one place, you are treating as a relation.
<% #tasks.each do |task| %>
Later in the code, you are trying to access it as a single object.
<% #tasks.completed.each do |task| %>
Since you are seeing the error on the second instance, you need to access 'completed' as in:
<% #tasks.completed.each do |task| %>
<% completed = task.completed %>
<% completed.each do |com| %>
Does this make sense?

Resources