Rails - How to create alphabetical system? - ruby-on-rails

I am getting data from my mySQL database with Ruby on Rails like that:
def all_specs
Specialization.order("title ASC").all;
end
Now, I would like to sort this data in the view file like that:
<div class="nav-column">
<h3>A</h3>
<ul class="submenu">
<li>All data that has title that starts with A</li>
</ul>
</div>
<div class="nav-column">
<h3>A</h3>
<ul class="submenu">
<li>All data that has title that starts with B</li>
</ul>
</div>
and so on from A-Z
How can I achieve that ?

You could group the data:
specs = Specialization.order("title ASC")
specs_by_first_letter = specs.group_by { |spec| spec.title[0] }
This returns a hash like:
{
"A" => [<Specialization title:"A...">, <Specialization title:"A...">],
"B" => [<Specialization title:"B...">, <Specialization title:"B...">],
...
"Z" => [<Specialization title:"Z...">, <Specialization title:"Z...">]
}
Looping through this hash should be quite easy. Note that some letters could be missing.

Thank you very much for all of your help. Zippie provided amazing solution!
Here is the implementation and iterating over hash for everyone:
<%
institutions_c = all_institution_categories
inst_by_first_letter = institutions_c.group_by { |inst| inst.title[0] }
%>
<% inst_by_first_letter.each do |key, value| %>
<div class="nav-column">
<h3><%= key %></h3>
<ul class="submenu">
<% value.each do |cat| %>
<li><%= link_to cat.title, institutions_path(:categories => cat.id), :title => cat.title %></li>
<% end %>
</ul>
</div>

Related

Dry up this httparty code and move it out of the controller and into the model

ArticlesController
def home
#url = 'https://meta.discourse.org/latest.json'
#forum_data = HTTParty.get(#url).parsed_response
#topic_one = #forum_data['topic_list']['topics'][0]['title']
#topic_two = #forum_data['topic_list']['topics'][1]['title']
#topic_three = #forum_data['topic_list']['topics'][2]['title']
#topic_four = #forum_data['topic_list']['topics'][3]['title']
#topic_five = #forum_data['topic_list']['topics'][4]['title']
end
articles/home.html.erb
<div class="topics">
<ul>
<li>
<%= #topic_one %>
</li>
<li>
<%= #topic_two %>
</li>
<li>
<%= #topic_three %>
</li>
<li>
<%= #topic_four %>
</li>
<li>
<%= #topic_five %>
</li>
</ul>
</div>
I am struggling with how I can pass the integer into the object as a variable and I am also struggling with how I can create a method to move this into the model.
You can wrap it in a PORO:
class ForumTopicList
def initialize(discourse_forum_url)
#forum_url = discourse_forum_url
#forum_data = HTTParty.get(#url).parsed_response
end
def topics
#forum_data['topic_list']['topics'].map { |topic| ForumTopic.new(topic) }
end
class ForumTopic
def initialize(topic_hash)
#topic_hash = topic_hash
end
def title
#topic_hash['title']
end
end
end
This will allow you to reduce your controller to:
def home
url = 'https://meta.discourse.org/latest.json'
#topics = ForumTopicList.new(url).topics.first(5)
end
And your view can become
<div class="topics">
<ul>
<%= #topics.each do |topic|>
<li> <%= topic.title %> </li>
</ul>
</div>

Agenda calendar/roster view

I would like to display an agenda that shows who is available for roster for the next seven days, with the following logic:
Looping through each of the 7 days, for each day:
If the leave starts today, show Starts %H:%M
If the leave finishes today, show Finishes %H:%M
If the leave starts and finishes today, show %H:%M - %H:%M
If the leave doesn't start or finish today but spans over today, show all day
Should include leave that start or finish outside of the 7 days but span the 7 days being displayed.
I am hoping for someone to point me in the right direction preferably using Rails and Postgres. I am not against doing the queries for each day since at most there will only be 30 days displayed, but also looking for reasonably performant code since there could be 100+ leave records per day.
First example that does not fulfill the criteria outlined above.
<% #dates.each do |d| %>
<h5><%= d.strftime("%A %d %b") %></h5>
<% #leave = Leave.where('(start_at BETWEEN ? AND ?) OR (end_at BETWEEN ? AND ?)', d.beginning_of_day, d.end_of_day, d.beginning_of_day, d.end_of_day) %>
<% #leave = #leave.where.not('end_at < ?', Time.current) %>
<% if #leave.any? %>
<ul>
<% #leave.each do |leave| %>
<% if leave.single_day? && leave.start_at.to_date == d %>
<li>
<label class="label label-danger"><%= leave.start_at.strftime('%H:%M') %> - <%= leave.end_at.strftime('%H:%M') %></label>
<%= leave.user.name %>
</li>
<% elsif !leave.single_day? %>
<% if leave.start_at.to_date == d %>
<li>
<label class="label label-danger">From <%= leave.start_at.strftime('%H:%M') %></label>
<%= leave.user.name %>
</li>
<% elsif leave.end_at.to_date == d %>
<li>
<label class="label label-danger">Until <%= leave.end_at.strftime('%H:%M') %></label>
<%= leave.user.name %>
</li>
<% else %>
<li>
<label class="label label-danger">All Day</label>
<%= leave.user.name %>
</li>
<% end %>
<% end %>
<% end %>
</ul>
<br/>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.where.not(id: #leave.map(&:user_id)).count %> Available
<% else %>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.count %> Available
<% end %>
<br />
<br />
<% end %>
I would start with something like this:
In the model:
def starts_on?(date)
start_at.to_date == date
end
def ends_on?(date)
end_at.to_date = date
end
def covers?(date)
leave.start_at.to_date <= date && leave.end_at.to_date >= date
end
def starts_and_ends_on?(date)
starts_on?(date) && ends_on?(date)
end
In the controller:
#dates = # define the date range like you already do, I assume it is an array
#leaves = Leave.includes(:user).
where('start_at =< ? AND end_at >= ?', dates.max, dates.min)
In the helper:
def relevant_leaves_for_date(date, leaves)
leaves.select { |leave| leave.covers?(date) }
end
def leave_description_for_date(leave, date)
if leave.starts_and_ends_on?(date)
"#{leave.start_at.strftime('%H:%M')} - #{leave.end_at.strftime('%H:%M')}"
elsif leave.starts_on?(date)
"From #{leave.start_at.strftime('%H:%M')}"
elsif leave.ends_on?(date)
"Until #{leave.end_at.strftime('%H:%M')}"
else
'All day'
end
end
def available_users(leaves)
current_account.users.active.count - leaves.size
end
In the view:
<% #dates.each do |date| %>
<h5><%= date.strftime("%A %d %b") %></h5>
<% leaves = relevant_leaves_for_date(date, #leaves) %>
<% if leaves.any? %>
<ul>
<% leaves.each do |leave| %>
<li>
<label class="label label-danger">
<%= leave_description_for_date(leave, date) %>
</label>
<%= leave.user.name %>
</li>
<% end %>
</ul>
<% end %>
<span class="label label-success">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= available_users(leaves) %> Available
<% end %>
You might notice that I remove the <br> and style tags from the html. Please do not use <br> for styling or style attributes in the html. Add class the the tags and style them in your css file.
The reason why case 4 & 5 are not working is you are not fetching the leaves which started before the beginning of day or which are going to end after the end of day. So you can fetch all leaves which have not ended yet.
<% #leave = Leave.where('(end_at >= ?', d.beginning_of_day) %>
And then in application_helper.rb, you can have a function like this,
def check_for_leave(leave,d)
msg = ""
if leave.single_day? && leave.start_at.to_date == d
msg = "#{leave.start_at.strftime('%H:%M')} - #{leave.end_at.strftime('%H:%M')}"
elsif !leave.single_day?
if leave.start_at.to_date == d
msg = "From #{leave.start_at.strftime('%H:%M')}"
elsif leave.end_at.to_date == d
msg = "Until #{leave.end_at.strftime('%H:%M')}"
else
msg = "All Day"
end
return msg
end
In html.erb file
<% #dates.each do |d| %>
<h5><%= d.strftime("%A %d %b") %></h5>
<% #leave = Leave.where('(end_at >= ?', d.beginning_of_day) %>
<% if #leave.any? %>
<ul>
<% #leave.each do |leave| %>
<li>
<label class="label label-danger">
<%= check_for_leave(leave, d) %>
</label>
<%= leave.user.name %>
</li>
<% end %>
</ul>
<br/>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.where.not(id: #leave.map(&:user_id)).count %> Available
<% else %>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.count %> Available
<% end %>
<br />
<br />
<% end %>

Rails ActionView::Template::Error: undefined method for Nill class

I know that this is quite a common problem but none of the other responses has been able to help me.
I am currently trying to create tests for my website but I always get the error
ActionView::Template::Error: undefined method
for quite a lot of my methods which usually result in a Nill class. The website uses devise for logging in.
Here is a test that I'm trying to run. I made sure my fixtures are loaded into the test database
require 'test_helper'
class PagesControllerTest < ActionController::TestCase
include Devise::TestHelpers
include Warden::Test::Helpers
Warden.test_mode!
def setup
sign_in User.first
end
def teardown
Warden.test_reset!
end
test "should get index" do
get :index
assert_response :success
end
test "should get voting" do
get :voting
assert_response :success
end
end
And these are the error messages when trying to run the test
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `strip' for nil:NilClass
config/initializers/addChallenges.rb:22:in `findChallenges'
app/views/pages/index.html.erb:11:in `_app_views_pages_index_html_erb__190802989_69818040'
test/controllers/pages_controller_test.rb:18:in `block in <class:PagesControllerTest>'
config/initializers/addChallenges.rb:22:in `findChallenges'
app/views/pages/index.html.erb:11:in `_app_views_pages_index_html_erb__190802989_69818040'
test/controllers/pages_controller_test.rb:18:in `block in <class:PagesControllerTest>'
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `strip' for nil:NilClass
config/initializers/addIdeas.rb:25:in `findIdeas'
app/views/pages/voting.html.erb:6:in `_app_views_pages_voting_html_erb___557022735_70668940'
test/controllers/pages_controller_test.rb:24:in `block in <class:PagesControllerTest>'
config/initializers/addIdeas.rb:25:in `findIdeas'
app/views/pages/voting.html.erb:6:in `_app_views_pages_voting_html_erb___557022735_70668940'
test/controllers/pages_controller_test.rb:24:in `block in <class:PagesControllerTest>'
Finished in 0.31402s
2 tests, 0 assertions, 0 failures, 2 errors, 0 skips
Process finished with exit code 0
When tracking the error in this case, this line is shown as problematic resp = http.get(url.path, headers) This is my full addIdeas code but the addChallenges one is quite similar.
class AddIdeas
#a method that will find all the challenge ideas for a user and then store them in our databse
def self.findIdeas(email,challengeId)
require "net/http"
require "uri"
require 'json'
require 'active_record'
p= People.find_by_email(email)
uri_string = 'http://sideways6.com/api/V1/Idea/Challenge/'
uri_string << challengeId.to_s
#make the http request with the headers
url = URI.parse(uri_string)
http = Net::HTTP.new(url.host, url.port)
headers = {
'Authorization' => p.basic,
'UserId' => p.userId,
'AuthorizationToken' => p.auth_tok
}
#retrieve a get response
resp = http.get(url.path, headers)
#if response is okay parse the challenge ids and add them to the person table for that user
if resp.code.to_s == '200'
if resp.body.to_s != 'null'
puts parsed = JSON.parse(resp.body)
ids = ""
parsed.each do |element|
addIdeas(element, challengeId)
ids << "#{element['IdeaId']},"
end
c = Challenges.find_by_challengeId(challengeId)
c.ideaIds = ids
c.save
end
end
end
def self.addIdeas(element, challengeId)
i = Ideas.find_by_ideaId(element['IdeaId'])
if i == nil
i = Ideas.create(:ideaId => element['IdeaId'], :title => element['Title'], :description => element['Description'], :challengeIds => challengeId, :score=>1000, :faceOff => 0, :wins =>0)
end
if i != nil
i.ideaId = (element['IdeaId'])
i.title = (element['Title'])
i.description = (element['Description'])
i.challengeIds = challengeId
i.save
end
end
def self.findAllIdeas(email)
p = People.find_by_email(email)
ids = p.challenges
splitted = ids.split(",")
counter = splitted.length
i =0
while i < counter.to_i do
findIdeas(email, splitted[i])
i += 1
end
end
end
addChallenges file
class AddChallenges
#a method that will find all the challenge ideas for a user and then store them in our databse
def self.findChallenges(email)
require "net/http"
require "uri"
require 'json'
require 'active_record'
p= People.find_by_email(email)
#make the http request with the headers
url = URI.parse('http://sideways6.com/api/V1/Challenge/All')
http = Net::HTTP.new(url.host, url.port)
headers = {
'Authorization' => p.basic,
'UserId' => p.userId,
'AuthorizationToken' => p.auth_tok
}
#retrieve a get response
resp = http.get(url.path, headers)
#if response is okay parse the challenge ids and add them to the person table for that user
if resp.code.to_s == '200'
puts parsed = JSON.parse(resp.body)
ids = ""
parsed.each do |element|
addChallenges(element)
ids << "#{element['ChallengeId']},"
end
p = People.find_by_email(email)
p.challenges = ids
p.save
end
end
def self.addChallenges(element)
c = Challenges.find_by_challengeId(element['ChallengeId'])
if c == nil
c = Challenges.create(:challengeId => element['ChallengeId'], :title => element['Title'], :description => element['Description'])
end
if c != nil
c.challengeId = (element['ChallengeId'])
c.title = (element['Title'])
c.description = (element['Description'])
c.save
end
end
def self.retrieveChallengeObject(challengeId)
c = Challenges.find_by_challengeId(challengeId)
end
end
My pages controller as requested
class PagesController <ApplicationController
def home
#current_nav_identifier = :home
end
end
Index page
<script type="text/javascript">window._token = '<%= form_authenticity_token %>';</script>
<body>
<noscript>
<div class='warning-page-cover'>
<div class='alert alert-info'>
<h2>Sorry about that, it appears that you are using a web browser without JavaScript which prevents us offering you a rich online experience.</h2>
<p>Please enable JavaScript or use a different web browser, or alternatively contact the CiCS Helpdesk for assistance.</p>
</div>
</div>
</noscript>
<%AddChallenges.findChallenges(current_user.email)%>
<%AddIdeas.findAllIdeas(current_user.email)%>
<div id='wrap'>
<nav class='navbar navbar-default navbar-fixed-top' id='main-nav'>
<div class='container-fluid'>
<div class='navbar-header'>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
<a href="<%= url_for(:controller=> 'pages', :action => 'index')%>">
<%= image_tag('/logo.png', :alt => "Sideways 6 Logo", size:"203x50") %>
</a>
</div>
<div class='collapse navbar-collapse' id="bs-example-navbar-collapse-1">
<ul class='nav navbar-nav'>
</ul>
<% if true # user_signed_in? %>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to fa_icon('index', text: 'Refresh Challenges'), root_path , method: :get %></li>
<li class="dropdown">
<%= link_to '#', data: { toggle: :dropdown }, class: 'dropdown-toggle' do %>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
<% p = People.find_by_email(current_user.email)%>
<% fName = p.firstName %>
<% if fName != nil %>
<%= fa_icon('user', text: fName )%>
<%end%>
<% if fName == nil %>
<%= fa_icon('user', text: current_user.email) %>
<%end%>
<b class="caret"></b>
<% end %>
<ul class="dropdown-menu">
<li>
<%# log out path is usually: destroy_user_session_path %>
<%= link_to fa_icon('index', text: Score.retrieveUserScore(current_user.email)), root_path , method: :get %>
<%= link_to fa_icon('challenges', text:'All Challenges'), challenges_path, method: :get, title: "See all Challenges" %>
<%= link_to fa_icon('sign-out', text: 'Log out'), destroy_user_session_path, method: :get, title: "Log out of the system" %>
</li>
</ul>
</li>
</ul>
<% end %>
</div>
</div>
</nav>
<div id="main">
<h1>Select A Challenge To Vote On</h1>
<% p = People.find_by_email(current_user.email) %>
<% ids = p.challenges %>
<% splitted = ids.split(",") %>
<% counter = splitted.length %>
<p class="lead">Please Select One</p>
<% i =0 %>
<% while i < counter.to_i do %>
<div class="row">
<div class="col-xs-12 col-md-6">
<% c = AddChallenges.retrieveChallengeObject(splitted[i]) %>
<% if Vote.canVote(splitted[i]) == true %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(splitted[i])%>" class="challenge-select" data-challengeid="<%=(splitted[i])%>">
<div class="well clickable">
<h4><%= c.title %></h4>
<p class="text-center"> <%= c.description %> </p>
</div>
</a>
<% end %>
</div>
<% i+=1 %>
<% if i != counter %>
<div class="col-xs-12 col-md-6">
<% c = AddChallenges.retrieveChallengeObject(splitted[i]) %>
<% if Vote.canVote(splitted[i]) == true %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(splitted[i])%>" class="challenge-select" data-challengeid="<%=(splitted[i])%>">
<div class="well clickable">
<h4><%= c.title %></h4>
<p class="text-center"><%= c.description %></p>
</div>
</a>
<% end %>
</div>
<%end%>
</div>
<% i+=1 %>
<%end%>
<%= yield %>
</div>
</div>
And voting html
<script type="text/javascript">window._token = '<%= form_authenticity_token %>';</script>
<% require 'digest/sha1'
salt = '%+5)_' %>
<% AddIdeas.findIdeas(current_user.email,params[:challengeId]) %>
<% if params[:winner] != nil
concat = "#{salt}#{params[:challengeId]}#{params[:winner]}#{params[:loser]}#{salt}"
hash = Digest::SHA1.hexdigest(concat)
if hash == params[:hash]
Score.updateScore(params[:winner],params[:loser])
Score.userScore(current_user.email)
end
end %>
<div id='wrap'>
<nav class='navbar navbar-default navbar-fixed-top' id='main-nav'>
<div class='container-fluid'>
<div class='navbar-header'>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
<a href="<%= url_for(:controller=> 'pages', :action => 'index')%>">
<%= image_tag('/logo.png', :alt => "Sideways 6 Logo", size:"203x50") %>
</a>
</div>
<div class='collapse navbar-collapse' id="bs-example-navbar-collapse-1">
<ul class='nav navbar-nav'>
</ul>
<% if true # user_signed_in? %>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to fa_icon('index', text: 'Change Challenge'), root_path , method: :get %></li>
<li class="dropdown">
<%= link_to '#', data: { toggle: :dropdown }, class: 'dropdown-toggle' do %>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
<% p = People.find_by_email(current_user.email)%>
<% fName = p.firstName %>
<% if fName != nil %>
<%= fa_icon('user', text: fName )%>
<%end%>
<% if fName == nil %>
<%= fa_icon('user', text: current_user.email) %>
<%end%>
<b class="caret"></b>
<% end %>
<ul class="dropdown-menu">
<li>
<%# log out path is usually: destroy_user_session_path %>
<%= link_to fa_icon('index', text: Score.retrieveUserScore(current_user.email)), root_path , method: :get %>
<%= link_to fa_icon('challenges', text:'All Challenges'), challenges_path, method: :get, title: "See all Challenges" %>
<%= link_to fa_icon('sign-out', text: 'Log out'), destroy_user_session_path, method: :get, title: "Log out of the system" %>
</li>
</ul>
</li>
</ul>
<% end %>
</div>
</div>
</nav>
<div id="main">
<% c = Challenges.find_by_challengeId(params[:challengeId]) %>
<% ids = c.try(:ideaIds) %>
<% splitted = ids.try(:split, ",") %>
<% shuffle = splitted.try(:shuffle) %>
<% firstIdea = shuffle.try(:first) %>
<% lastIdea = shuffle.try(:last) %>
<% f = Ideas.find_by_ideaId(firstIdea)%>
<% l = Ideas.find_by_ideaId(lastIdea)%>
<h1><%=c.try(:title)%></h1>
<p class="lead">Which best solves the challenge?</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<% challengeId = params[:challengeId]
winner = f.try(:ideaId)
loser = l.try(:ideaId)
concat = "#{salt}#{challengeId}#{winner}#{loser}#{salt}"
hash = Digest::SHA1.hexdigest(concat) %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(params[:challengeId])%>&winner=<%=(f.try(:ideaId))%>&loser=<%=(l.try(:ideaId))%>&hash=<%=(hash)%>" class="idea-vote" data-challengeid="<%=(params[:challengeId])%>" data-winner="<%=(f.try(:ideaId))%>" data-loser="<%=(l.try(:ideaId))%>" data-hash="<%=(hash)%>">
<div class="well clickable">
<h4><%= f.try(:title) %></h4>
<p class="text-center"><%= f.try(:description)%></p>
</div>
</a>
</div>
<div class="col-xs-12 col-md-6">
<% challengeId = params[:challengeId]
winner = l.try(:ideaId)
loser = f.try(:ideaId)
concat = "#{salt}#{challengeId}#{winner}#{loser}#{salt}"
hash = Digest::SHA1.hexdigest(concat) %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(params[:challengeId])%>&winner=<%=(l.try(:ideaId))%>&loser=<%=(f.try(:ideaId))%>&hash=<%=(hash)%>" class="idea-vote" data-challengeid="<%=(params[:challengeId])%>" data-winner="<%=(l.try(:ideaId))%>" data-loser="<%=(f.try(:ideaId))%>" data-hash="<%=(hash)%>">
<div class="well clickable">
<h4><%=l.try(:title)%></h4>
<p class="text-center"><%=l.try(:description)%></p>
</div>
</a>
</div>
</div>
Skip <span class="glyphicon glyphicon-chevron-right"></span>
<%= yield %>
</div>
</div>
I have tried modifying the methods with try() and it seems to sometimes resolve the issue but after that the try() causes problems with the website itself. Sometimes the error message would redirect me to the html view file itself where methods are used.
EDIT:
Ok after fixing the headers I now get
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `split' for nil:NilClass
config/initializers/addIdeas.rb:61:in `findAllIdeas'
app/views/pages/index.html.erb:12:in `_app_views_pages_index_html_erb__1448445017_66568380'
test/controllers/pages_controller_test.rb:17:in `block in <class:PagesControllerTest>'
config/initializers/addIdeas.rb:61:in `findAllIdeas'
app/views/pages/index.html.erb:12:in `_app_views_pages_index_html_erb__1448445017_66568380'
test/controllers/pages_controller_test.rb:17:in `block in <class:PagesControllerTest>'
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `score' for #<People:0x000000085d17b0>
config/initializers/score.rb:50:in `retrieveUserScore'
app/views/pages/voting.html.erb:56:in `_app_views_pages_voting_html_erb___944539514_69504160'
test/controllers/pages_controller_test.rb:23:in `block in <class:PagesControllerTest>'
config/initializers/score.rb:50:in `retrieveUserScore'
app/views/pages/voting.html.erb:56:in `_app_views_pages_voting_html_erb___944539514_69504160'
test/controllers/pages_controller_test.rb:23:in `block in <class:PagesControllerTest>'
Finished in 0.53103s
2 tests, 0 assertions, 0 failures, 2 errors, 0 skips
Process finished with exit code 0
The score.rb file
class Score
def self.updateScore(winner, loser)
Math.exp(1)
w = Ideas.find_by_ideaId(winner)
l = Ideas.find_by_ideaId(loser)
# updatewinner
# games W played = get number of times the winner has matched up against other ideas
# winner new score = winner score + (1000/games W played) (1+ 1/(1 + Math.exp(loser score - winner score)))
w.faceOff += 1
w.save
lScore = l.score
wScore = w.score
wGames = w.faceOff
newWScore = wScore + (500/wGames)*(1-(1/(1 + Math.exp(lScore - wScore))))
l.faceOff += 1
l.save
lGames = l.faceOff
newLScore = lScore + (500/lGames)*(-1/(1+ Math.exp(wScore - lScore)))
puts "New Winner Score "
puts newWScore
w.score = newWScore
w.save
puts "New Loser Score "
puts newLScore
l.score = newLScore
l.save
puts newWScore
# updateloser
# games L played = get number of times the loser has matched up against other ideas
# loser new score = loser score + (1000/games L played) (1+ 1/(Math.exp(winner score - loser score)))
end
def self.userScore(email)
p = People.find_by_email(email)
score = p.score
newScore = score + 1
p.score = newScore
p.save
end
def self.retrieveUserScore(email)
p = People.find_by_email(email)
score = 'Score: ' << p.score.to_s
end
end
Ok, I did some testing:
Your error is that one of your header params is coming back from your database as nil
I can replicate your error by setting
headers = {
'Authorization' => nil,
'UserId' => nil,
'AuthorizationToken' => nil
}
and running http.get(url.path, headers)
What you can do to avoid the exception and let the API return an error is test for nil and replace it with an empty string ""
Ex: 'Authorization' => p.basic || ""
EDIT: For your edit above...
There are two errors:
ActionView::Template::Error: undefined method 'split' for nil:NilClass
This one happens because of:
ids = p.challenges
splitted = ids.split(",")
If ids is nil, you can't call split on it. You need to add a check and return at that point.
ActionView::Template::Error: undefined method 'score' for #<People:0x000000085d17b0>
Your People model doesn't have a score method

Create toggle-able Bootstrap tabs from Ruby hash

So I'm trying to create toggle-able tabs from a Ruby hash. For example, let's say that I have the following hash:
tabs = {
:Friends =>
[
[name: 'john', age: 20, sex: 'M'],
[name: 'elma', age: 21, sex: 'F']
],
:Family =>
[
[name: 'father', age: 50, sex: 'M'],
[name: 'mother', age: 48, sex: 'F'],
[name: 'sister', age: 17, sex: 'F']
]
}
This would result in the two tabs 'Friends' and 'Family' respectively which would list either friends or family members as an unordered list.
I would like to make this tabs toggle-able without Ajax if possible, so basically if I click the Friends tab it would access the appropriate value from the tabs[:Friends] hash.
Thanks!
Try this if it help you
Link to ur partial
<div id="toggle_div" style="display:none">
<%= render partial => "ur_partial" %>
</div>
By using JQuery
<script type="text/javascript">
$(function(){
$('.toggleLink').click(function(){
$('#toggle_div').toggle();
});
});
</script>
add different IDs to both tabs and toggle them...
Found the solution yesterday:
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
<li>
All
</li>
<% tabs.each do |k,v| %>
<li>
<a href="#<%= k.to_s %>" data-toggle="tab">
<%= k.to_s %>
</a>
</li>
<% end %>
</ul>
<div class="tab-content">
<div class = "tab-pane active" id = "all_tabs">
<ul>
<% tabs.each do |k,v| %>
<li>
<%=k%>
</li>
<% end %>
</ul>
</div>
<% tabs.each do |k,v| %>
<div class = "tab-pane" id = "<%= k.to_s %>">
<strong><%= k.to_s %></strong>
<ul>
<% v.each do |key,val| %>
<li>
<%=val.name%>
</li>
<% end %>
</ul>
</div>
<% end %>
</div>
</div>
Here is the generated html output:
http://www.bootply.com/0sWdURMEPY

passing dynamic variable to partial for rendering in a modal

I have the following Code on a partial that dynamically generates a list of associated steps to a pin. Both pins and steps have image(s). Users are able to add multiple steps to a pin and then this view dynamically generates a view of these steps. For each step there are associated image(s) which I'd like to pop-up as a modal. The challenge is I keep getting the following error:
"undefined local variable or method `step' for #<#:0x00000102f498d8>"
When I stub out rendering the partial, the modal appears basically blank but works. Any ideas How do I do this?
<div class="col-md-6">
<% (0..(Step.where("pin_id = ?", params[:id]).count)-1).each do |step| %>
<div class="col-md-12">
<div class="well">
<ul class="nav pull-right">
<% if current_user == #pin.user %>
<%= link_to edit_step_path((Step.where("pin_id = ?", params[:id]).fetch(step)), :pin_id => #pin.id) do %>
<span class="glyphicon glyphicon-edit"></span>
Edit
<% end %> |
<%= link_to Step.where("pin_id = ?", params[:id]).fetch(step), method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-trash"></span>
Delete
<% end %> |
<%= link_to new_step_image_path(:step_id => Step.where("pin_id = ?", params[:id]).fetch(step), :pin_id => #pin.id) do %>
Add
<span class="glyphicon glyphicon-picture"></span>
<% end %>
<% end %>
<% if StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count == 0 %>
<% else %>
| <a href="#StepImageModal" data-toggle="modal">
<span class="glyphicon glyphicon-picture"></span> (<%= StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count %> ) </strong>
</a>
<% end %>
</ul>
<strong> Step <%= step+1 %>
<p>
<%= Step.where("pin_id = ?", params[:id]).pluck(:description).fetch(step) %>
</p>
</div>
</div>
<%end %>
</div>
<div class="modal fade" id="StepImageModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Modal Header</h3>
</div>
<div class="modal-body">
<%= render :partial => 'pins/step_images',
:locals => { :step => step } %>
</div>
<div class="modal-footer">
Close
</div>
</div>
I don't get what you're trying to do here
Loop
As mentioned in the comments, you've got a loop which goes through your steps. However, outside the loop, you want to display the partial
The solution to your woes will either be to set an instance variable (not desired), or use another persistent data type. I'd do this:
#app/controllers/steps_controller.rb
def action
#step = {}
end
#app/views/steps/action.html.erb
<% (0..(Step.where("pin_id = ?", params[:id]).count)-1).each do |step| %>
<% #step[step.id.to_sym] = step.details %>
<% end %>
<%= render :partial => 'pins/step_images', :locals => { :step => #step } %>
unless
Some refactoring for you:
<% unless StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count == 0 %>
| <%= link_to "#StepImageModal", data: { toggle: "modal"} do %>
<span class="glyphicon glyphicon-picture"></span>(<%= StepImage.where("step_id = ?", Step.where("pin_id = ?", params[:id]).pluck(:id).fetch(step)).count %> ) </strong>
<% end %>
<% end %>

Resources