Rails view conditionals if/elsif on user fields - ruby-on-rails

I'm trying to show a table of user data on my site - so I'm using a loop that iterates over the users and displays their info. Before, it was really simple, but I wanted to add conditionals that handled cases where they might not have a city, state, or either entered. When I only have one case entered, it works fine. When I have both, it works fine. User location is defined in the model as a JOIN of city and state. So don't worry there. But when I have neither, it doesn't display the '---' that I want. What am I missing here?
<tr>
<% #user.each do |user| %>
<td><%= link_to user.username, public_profile_path(user.username) %><br/></td>
<% if user.state != nil and user.city != nil %>
<td><%= user.location %></td>
<% elsif user.state != nil and user.city == nil %>
<td><%= user.state %></td>
<% elsif user.state == nil and user.city != nil %>
<td><%= user.city %></td>
<% else %>
<td>---</td>
<% end %>
<% if user.phone != nil %>
<td><%= user.phone %></td>
<% else %>
<td>-</td>
<% end %>
<td><%= mail_to user.email.to_s, "Email this User", :cc => "michaelomchenry#gmail.com",
:subject => "Contact from Overflow Member" %></td>
</tr>
<% end %>

I'd add a helper method, called location_display or something along those lines that handled all the logic around what should be displayed.
def location_display(user)
return user.location if user.state && user.city
return user.state if user.state && user.city.blank?
return user.city if user.city && user.state.blank?
"----"
end
Then, in your view, just replace all those lines with:
<td><%= location_display(user) %></td>

Related

Two submission forms with form-tag on same page in rails

I have a weekly time entry form currently. How can i have another time entry form on the same page ? and these two forms need be submitted separately as different records. Any help would be appreciated .
Here is my code:-
show_weeks.html.erb
<div class="table-responisve>
<% if #dates != nil %>
<table class="table-bordered">
<thead>
<tr>
<% #dates.each do |date| %>
<th><%=date.to_s+","+date.strftime("%A").to_s %> </th>
<% end %>
</thead>
<tbody>
<tr>
<% #dates.each do |date| %>
<% if #time_entry %>
<td><%= text_field_tag "#{date}", #time_entry.hour_per_day["#{date}"], class: "dates" %></td>
<% else %>
<%if date < Date.today %>
<td> <%= text_field_tag "#{date}", "", class: "dates" %> </td>
<%else %>
<td><%= text_field_tag "#{date}", "", class: "dates" if date == Date.today && Time.now.strftime("%H").to_i >= 10 %> </td>
<% end %>
<% end %>
<% end %>
</tr>
<tr>
<% if #time_entry %>
<td colspan="2"> Please Enter your Comment </td>
<td colspan="5">
<% #time_entry.comments.each do |c| %>
<p><%= text_field_tag "Comment", c.message %> </p>
<% end %>
</td>
<%else%>
<td colspan="2"> Please Enter your Comment </td>
<td colspan="5"><%= text_field_tag "Comment", "" %>
</td>
<%end%>
</tr>
</tbody>
</table>
</div>
<button type="button" class="btn btn-primary"
id="save_entries">Submit</button>
<%= form_tag save_time_entries_path, method: 'post',
id:"save_time_entries" do %>
<%= hidden_field_tag "start_date", #dates.first%>
<%= hidden_field_tag "end_date", #dates.last%>
<%= hidden_field_tag "total_hours", "" %>
<%= hidden_field_tag "project_id", #project.id %>
<%= hidden_field_tag "time_entry", "" %>
<%= hidden_field_tag "message", "" %>
<% if #time_entry%>
<%= hidden_field_tag "time_entry_detail_id", #time_entry.id %>
<% end %>
<% end %>
<script>
$("#save_entries").click(function(){
var time_entry = []
var hours = 0;
var message = document.getElementById("Comment").value;
$('.dates').each(function() {
hours += Number($(this).val());
if ($(this).val() == 0)
{
time_entry.push($(this).attr('name'),0)
}else{
time_entry.push($(this).attr('name'),$(this).val())
}
});
if (hours > 60) {
alert("Total Hours Should be equal to 60");
return false;
}
else {
$("#message").val(message);
$("#time_entry").val(time_entry);
$("#total_hours").val(hours);
$("#save_time_entries").submit();
}
})
</script>
<%end%>
you can create 2 different forms with form_for, it shouldn't be a problem
I figure out solution. Using of two submission forms on same page is bad idea. So I have create previous weeks records by using after create call back and i given default values for TimeEntryDetail. Here it creates all weeks records in background. Suppose if you skipped for 6 weeks , it'll create 6 empty records in background. Here is my working code
Modal.rb
after_create :chceck_time
def check_time
#project_mem_check= ProjectMember.where(project_id: project, member_id: user).first.created_at
#present week dates coming here |
#time_entry_check = TimeEntryDetail.where(project_id: project, user_id: user).first.created_at
if #time_entry_check.nil?
#time_entry_check=#project_mem_check
end
#last_week_start=Date.today.beginning_of_week
#last_week_end =Date.today.end_of_week
#cheking project member creation shall be less than time entry creation of that project.
if #project_mem_check <= #time_entry_check
#time_check_first=TimeEntryDetail.where(project_id: project, user_id: user).pluck(:start_date).first.to_date
#time_check_last =TimeEntryDetail.where(project_id: project, user_id: user).pluck(:start_date).last.to_date
#check first entry == last time entry
if #time_check_first==#time_check_last
pm=ProjectMember.where(project_id: project, member_id: user).first.created_at.to_date
tm=Date.today.to_date
unfilled_weeks= ((tm-pm)/7).to_i+1
unfilled_weeks.times {
#last_week_start= #last_week_start-7
#last_week_end = #last_week_end-7
#call_back_entry=TimeEntryDetail.create(start_date: (#last_week_start).to_date, end_date: (#last_week_end).to_date,
project_id: project.id, user_id: user.id, hours: 0, aasm_state: "pending", hour_per_day: "" )
#call_back_entry.comments << Comment.create(message: "Please fill the timesheet ")
}
else
#Already this user have time entries and create empty records from where he stopped.
pm=created_at.to_date #--.present time entry is coming
tm=Date.today.to_date
unfilled_weeks= ((tm-pm)/7).to_i+1
unfilled_weeks.times{
#last_week_start= #last_week_start-7
#last_week_end = #last_week_end-7
#call_back_entry=TimeEntryDetail.create(start_date: (#last_week_start).to_date, end_date: (#last_week_end).to_date,
project_id: project.id, user_id: user.id, hours: 0, aasm_state: "submitted", hour_per_day: "" )
#call_back_entry.comments << Comment.create(message: "Not yet filled this week ")
}
end
end
end

Rails search with multiple queries not working

I know my code is clunky, but I am trying to have a form with multiple text boxes for different columns in my GUEST database. The form is not working and all my guest entries are still listed (the list is not narrowed down by the search). If anyone could possibly point me in the correct direction that would be awesome. Also how could the guest.rb code be more concise?
Controller:
def index
#guests = Guest.all
if params[:search_first_name]
#guests = Guest.search_first_name(params[:search_first_name])
end
if params[:search_last_name]
#guests = Guest.search_last_name(params[:search_last_name])
end
if params[:search_email]
#guests = Guest.search_email(params[:search_email])
end
if params[:search_phone]
#guests = Guest.search_phone(params[:search_phone])
end
end
guest.rb
def self.search_first_name(query)
# where(:email, query) -> This would return an exact match of the query
where("first_name like ?", "%#{query}%")
end
def self.search_last_name(query)
# where(:email, query) -> This would return an exact match of the query
where("last_name like ?", "%#{query}%")
end
def self.search_email(query)
# where(:email, query) -> This would return an exact match of the query
where("email like ?", "%#{query}%")
end
def self.search_phone(query)
# where(:email, query) -> This would return an exact match of the query
where("phone like ?", "%#{query}%")
end
index.html:
<%= form_tag(guests_path, :method => "get", class: "navbar-form", id: "search-form") do %>
<div class="input-append col-sm-10">
<div class="row">
<div class="col-sm-4">
<p><%= text_field_tag :search_first_name, params[:search_first_name], placeholder: "First Name", style: "width:100%;" %></p>
<p><%= text_field_tag :search_last_name, params[:search_last_name], placeholder: "Last Name", style: "width:100%;" %></p>
</div>
<div class="col-sm-4">
<p><%= text_field_tag :search_email, params[:search_email], placeholder: "Email Address", style: "width:100%;" %></p>
<p><%= text_field_tag :search_phone, params[:search_phone], placeholder: "Phone Number", style: "width:100%;" %></p>
</div>
<div class="col-sm-4">
</div>
<%= submit_tag 'Search Guests' %>
</div>
</div>
<% end %>
<table class="table table-hover col-sm-12">
<thead>
<tr>
<th>Guest ID</th>
<th>Guest Name</th>
<th>Email</th>
<th>Phone</th>
<th></th>
</tr>
</thead>
<tbody>
<% #guests.each do |guest| %>
<tr>
<td>G-00<%= guest.id %></td>
<td><%= guest.first_name %> <%= guest.last_name %></td>
<td><%= guest.email %></td>
<td><%= guest.phone %></td>
<td style="text-align:right;"><%= link_to 'View Guest Profile', guest, :class => "btn btn-sm btn-success" %> <%= link_to 'Edit', edit_guest_path(guest), :class => "btn btn-sm btn-default" %> <%= link_to 'Destroy', guest, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-sm btn-danger" %></td>
</tr>
<% end %>
</tbody>
</table>
The problem comes because a param without a value will be equal to "" which is still true in Ruby, so basically if your search_phone is ever empty then you'll see all the results because if params[:search_phone] will be true and so that block will be run, and the eventual code that's run will be equivalent to:
#guests = Guest.where( "phone like '%%'" )
Which is just two wildcards, and will therefore return all results. Other people have already mentioned changing that conditional to use .present? so it won't be run if it's blank.
You also asked about refactoring the code, I would write it like so:
controller
def index
#guests = Guest.search_or_all params
end
model
def self.search_or_all params={}
query = %i[first_name last_name email phone].map do |k|
kk = "search_#{k}"
sanitize_sql ["#{k} LIKE '%s'", "%#{params[kk]}%"] if params[kk]
end.compact.join " OR "
where query
end
Without going deep into a code refactoring. Try adding params[:field_name].present? to all the if statements.
You should put "^#{query}" to make this work as a regular expression.
This way your Guest.rb file will look like this
Guest.rb
def self.search_first_name(query)
# where(:email, query) -> This would return an exact match of the query
where("first_name like ?", "^#{query}")
end
def self.search_last_name(query)
# where(:email, query) -> This would return an exact match of the query
where("last_name like ?", "^#{query}")
end
def self.search_email(query)
# where(:email, query) -> This would return an exact match of the query
where("email like ?", "")
end
def self.search_phone(query)
# where(:email, query) -> This would return an exact match of the query
where("phone like ?", "%#{query}%")
end

Configure Sunspot Solr search with scope

Controller
class GearsController < ApplicationController
before_action :set_gear, only: [:show, :edit, :update, :destroy]
def primary
#gears = Gear.search do
with(:Lab, 'Primary')
order_by(:RU, :desc)
end
end
Model
class Gear < ActiveRecord::Base
validates_uniqueness_of :Nic1mac, :Nic2mac, :Nic3mac, :IBmac, :SN, :allow_blank => true
attr_readonly :Devtype, :Nic1mac, :Nic2mac, :Nic3mac, :IBmac, :SN
scope :Mini, -> { where(lab: 'Mini') }
scope :Primary, -> { where(lab: 'Primary') }
scope :Support, -> { where(lab: 'Support') }
scope :M5, -> { where(lab: 'M5') }
scope :P5, -> { where(lab: 'P5') }
searchable do
integer :RU
text :Devname
text :Devtype
string :Lab
text :Swportib
text :Swport1
text :Swport2
text :Swport3
text :IBip
text :Nic1
text :Nic2
text :Nic3
text :Nic1mac
text :Nic2mac
text :Nic3mac
text :IBmac
text :Psu1
text :Psu2
text :SN
end
end
View
<% provide(:title, "SP4 Primary") %>
<p id="notice"><%= notice %></p>
<h1>SP4 Primary</h1>
<%= form_tag gears_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<head>
<style>
table, th, td { border: 1px solid black;}
th, td { padding: 15px;}
</style>
</head>
<table>
<thead>
<tr>
<th>RU</th>
<th>Dev Name</th>
<th>Dev Type</th>
<th>Lab</th>
<th>SW PortIB</th>
<th>SW Port1</th>
<th>SW Port2</th>
<th>SW Port3</th>
<th>IB IP</th>
<th>NIC1</th>
<th>NIC2</th>
<th>NIC3</th>
<th>NIC1 Mac</th>
<th>NIC2 Mac</th>
<th>NIC3 Mac</th>
<th>IB Mac</th>
<th>PSU1</th>
<th>PSU2</th>
<th>SN</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #gears.each do |gear| %>
<tr>
<td><%= gear.RU %></td>
<td><%= gear.Devname %></td>
<td><%= gear.Devtype %></td>
<td><%= gear.Lab %></td>
<td><%= gear.Swportib %></td>
<td><%= gear.Swport1 %></td>
<td><%= gear.Swport2 %></td>
<td><%= gear.Swport3 %></td>
<td><%= gear.IBip %></td>
<td><%= gear.Nic1 %></td>
<td><%= gear.Nic2 %></td>
<td><%= gear.Nic3 %></td>
<td><%= gear.Nic1mac %></td>
<td><%= gear.Nic2mac %></td>
<td><%= gear.Nic3mac %></td>
<td><%= gear.IBmac %></td>
<td><%= gear.Psu1 %></td>
<td><%= gear.Psu2 %></td>
<td><%= gear.SN %></td>
<td><%= link_to 'Show', gear %></td>
<td><%= link_to 'Edit', edit_gear_path(gear) %></td>
<td><%= link_to 'Destroy', gear, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
Above is my Controller and Model code. I am trying to set up the search so it only searches through records within the scope specified. Currently it will return all results and does not pay attention to the scope. I believe I am close to making it work but just don't have the right syntax. Then again I may be wrong, thus any help suggestions or different ways of doing this are welcome.
You can add a code like this in your search method
with(:lab, 'Support')
and in your model add this
string :lab
The solution was adding without in my gears_controller.rb file.
gears_controller.rb
def rack1
#gears = Gear.where("Lab like ? OR Lab like ? OR Lab like ?", "%Primary%", "%Mini%", "%Support%")
#search = Gear.search do
fulltext params[:search]
without(:Lab, "P5")
without(:Lab, "M5")
order_by(:RU, :desc)
end
#gears = #search.results
end
Adding the without fields allowed me to only search through the records with the specific Lab values that were specified in my #gears variable.

Pagination not working correctly in rails

I am trying to use will_paginate for a list of items I want to display.
There is a form with drop down selections to fetch objects by status.
This is my controller
def list
#person = Person.find_by_id(session[:person_id])
params[:status] = params[:redirect_status] if params.has_key?('redirect_status')
#statuses = Peptide.statuses
#status = 'Not Ordered'
#status = params[:status] if params[:status] != nil || params[:status] == ''
#peptides = Peptide.find(:all, :conditions => ['status = ?', #status]).paginate(:per_page => 30, :page => params[:page])
if Peptide.count.zero?
flash[:notice] = "There are not any peptides entered"
redirect_to :action => 'new'
end#if zero
end
This is in the view
<form action="/peptide/create_spreadsheet_of_not_ordered" enctype="multipart/form-data" method="post">
<table class="sortable" cellpading="5" cellspacing="2" width="100">
<tr class= "header-line">
<th>SS</th>
<th>Status</th>
<th>Peptide</th>
<th>Gene</th>
<th>Submitter</th>
<th>Created</th>
<th>Updated</th>
<th>Sequence</th>
<th>Modification</th>
<th>Vendor</th>
</tr>
<% for #peptide in #peptides.reverse %>
<tr valign = "top" class= "<%= cycle('color_one', 'color_two') %>">
<!--an error here during development likely indicates that the people table has not be repopulated or
that no submitter primer is present for a primer-->
<td sorttable_customkey = 0 > <%=check_box_tag "box[]", #peptide.id %>
<td><%= #peptide.status%></td>
<td class><%= link_to #peptide.name, :action => :report, :id => #peptide.id %></td>
<td><%= gene_links(#peptide.genes) rescue 'Error'%></td>
<td><%= #peptide.submitter.name rescue "" %></td>
<td <%= sorttable_customkey_from_date(#peptide.created_at)%> >
<%= #peptide.created_at.strftime("%b %d %Y") rescue "Unknown"%>
</td>
<td <%= sorttable_customkey_from_date(#peptide.updated_at)%> >
<%= #peptide.updated_at.strftime("%b %d %Y") rescue "Unknown"%>
</td>
<td><%= #peptide.sequence%></td>
<td><%= #peptide.modifications%></td>
<td><%= #peptide.vendor%></td>
<%= buttons() %>
</tr>
<%end%>
<%= will_paginate #peptides %>
</table>
<br>
<%= submit_tag "Create Spreadsheet"%>
The default list is grouped by status ordered.
however when I select any other status and submit the form the pagination links take me back to the default status.
Please help me resolve this issue.
Thanks
Without seeing the view, it sounds like you need to add the current params as an argument to the links for the other statuses...
Update
Try adding the params to your status link:
<%= link_to #peptide.name, peptide_path(#peptide, params), :action => :report, :id => #peptide.id %>
The documentation is here.

Table with list of fields

I'm trying to put together a table with seven columns for a schedule. On each column I want to list twenty fields. I playing around but I cannot find the way to make it work.
Controller:
def new
#doctor = Doctor.new
140.times { #doctor.schedules.build }
end
Model:
has_many :schedules
def schedule_attributes=(schedule_attributes)
schedule_attributes.each do |attributes|
schedules.build(attributes)
end
end
Form:
<tr>
<% #doctor.schedules.each_with_index do |schedule, i| %>
<td>
<% if i > 0 && i % 20 == 0 %>
</td>
<td>
<% end %>
<%= fields_for "doctor[schedule_attributes][]", schedule do |schedule_form| %>
<ul>
<% schedule_form.text_field :day, value: #days[0] %>
<li><%= schedule_form.check_box :hour, value: "8:00" %></li>
</ul>
<% end %>
</td>
<% end %>
</tr>
This only outputs forty fields. The idea is output 140 fields, twenty in each column.
I would like to insert the twenty fields in one single cell. Can somebody point me on the right direction?
Using a simple (quick and dirty) approach, you can do this:
<tr>
<td>
<% #doctor.schedules.limit(140).each_with_index do |schedule, i| %>
<% if i > 0 && i % 20 == 0 %>
</td>
<td>
<% end %>
<%= fields_for "doctor[schedule_attributes][]", schedule do |schedule_form| %>
<ul>
<% schedule_form.text_field :day, value: #days[0] %>
<li><%= schedule_form.check_box :hour, value: "8:00" %></li>
</ul>
<% end %>
<% end %>
</td>
</tr>
If you want to reuse this logic, a helper method should be used:
def to_columns(collection, num_columns)
html = ""
count = collection.size
num_rows = (count / num_columns.to_f).ceil
collection.each_with_index do |item, i|
html << '<td>'.html_safe if (i % num_rows == 0)
html << yield(item, i)
html << '</td>'.html_safe if (i % num_rows == 0 || i == (count - 1))
end
html
end
And in your view, let this method make your <td> tags as needed:
<tr>
<%= to_columns(#doctor.schedules.limit(140), 7) do |schedule, i| %>
<%= fields_for "doctor[schedule_attributes][]", schedule do |schedule_form| %>
<ul>
<% schedule_form.text_field :day, value: #days[0] %>
<li><%= schedule_form.check_box :hour, value: "8:00" %></li>
</ul>
<% end %>
<% end %>
</tr>

Resources