nil:NilClass when ByeBug reports expected outcome - ruby-on-rails

I am trying to access my dirts/index page, but I am getting this error shown in the picture below.
So I put a byebug in the #total_trip_miles to see what is going on:
class Driver < ApplicationRecord
has_many :dirts
validates :name, presence: true, uniqueness: true
def total_trip_miles
byebug
collect_trip_miles.round.to_s
end
def average_speed
total_distance = collect_trip_miles
total_rate = collect_trip_seconds
((total_distance/total_rate)*3600).round
end
def collect_trip_miles
dirts.map do |trip|
trip.distance.to_f
end.inject(:+)
end
def collect_trip_seconds
seconds = []
dirts.map do |trip|
seconds << trip.change_in_time(trip.start_time, trip.end_time)
end
seconds.inject(:+)
end
end
When I call the collect_trip_miles.round.to_s from byebug I get "55", which is exactly what I want to pass my spec:
I call the method from #drivers in the dirt/index.html.erb:
<ul id="trips">
<% drivers.each do |driver| %>
<li>
<article class="driver">
<header>
<h2><%= show_name_of(driver) %></h2>
</header>
<p>
<%= "#{show_total_miles_of(driver)} Miles" %>
</p>
<table>
</table>
<footer>
</footer>
</article>
</li>
<% end %>
</ul>
And those methods are called from my app/helpers/dirts_helper.rb
module DirtsHelper
def show_name_of(driver)
the_driver(driver).name.capitalize
end
def show_total_miles_of(driver)
the_driver(driver).total_trip_miles
end
def the_driver(driver)
Driver.find(driver.first)
end
def drivers
#driver_store = {}
#drivers.each_with_index do |driver, dirts|
#driver_store[driver.id] = driver.dirts
end
#driver_store
end
end
And then the controller action comes from app/controllers/dirts_controller.rb
class DirtsController < ApplicationController
def index
#drivers = Driver.all
end
end
Based on what I've described and shown evidence for, is there some-super-obvious-I-should-be-ashamed-of-myself reason why my driver model's methods are blowing up in my localhost but debugging is reporting as expected?

Could it be this?
def the_driver(driver)
Driver.find(driver.first)
end
You are iterating drivers.each do |driver| in your view, do when you pass it into show_total_miles_of and then subsequently the_driver, you should not have to find it, as you are already dealing with a single instance of an object.

I made the mistake of not guarding against nil in my collection of drivers, some of them don't have any trip miles. So, calling #round on nothing is throwing an error but it works in ByeBug because that is just capturing one item in the collection that just so happens to have miles as well and so calling #round on the Float works.

Related

How do I use the Enumerable mixin in my presenter?

I've got a presenter which I would like to make the each_with_index method available in. I've added include Enumerable in my base presenter however, I'm still getting a no method error. My current code is below:
index.erb
<% #bids.each_with_index do |bid, index| %>
<% present bid do |bid_presenter| %>
<div class="large-4 medium-4 columns <%= bid_presenter.last_column %>"></div>
<% end %>
<% end %>
bid_presenter.rb
class BidPresenter < BasePresenter
presents :bid
def last_column
if index == bid.size - 1
'end'
end
end
end
base_presenter.rb
class BasePresenter
include Enumerable
def initialize(object, template)
#object = object
#template = template
end
private
def self.presents(name)
define_method(name) do
#object
end
end
# h method returns the template object
def h
#template
end
# if h is missing fallback to template
def method_missing(*args, &block)
#template.send(*args, &block)
end
end
bids_controller.erb
# GET /bids
# GET /bids.json
def index
#bids = current_user.bids
end
You are forwarding all not explicitly implemented methods to #template. Whatever #template is doesn't seem to properly implement each. You need to make #template respond properly to each.

Rails4 about helper_method

I have question about helper_method.
When I add fuc in /controller/application_controller.rb
helper_method :values
def values
#food = Food.all
#food_type = FoodType.all
end
I want to use var on /layouts/application.html.erb
code here
<% #food.each do |fp|%>
<p><%= fp.name %></p>
<% end %>
<% #food_type.each do |ft|%>
<p><%= ft.name %></p>
<% end %>
but it return nill .
Please teach me ,thx a lot
You can try this
application_controller.rb
def values
#food = Food.all
#food_type = FoodType.all
[#food, #food_type]
end
application.html.erb
<%food, food_type = values%>
<% food.each do |fp|%>
<p><%= fp.name %></p>
<% end %>
<% food_type.each do |ft|%>
<p><%= ft.name %></p>
<% end %>
DRY
You'll be much better using the before_action callback
The problem you have is a helper is meant as a simple way to create functionality for your application. IE that you pass some data to the helper, it will "crunch" the data, and return a reasonable response.
This is why Vimsha's answer has been accepted - he has made it so that your helper method will return the values you need; consequently meaning you need to call the method if you want to use the data it has .
--
The real answer for you (considering you just want to be able to use the #food and #food_type variables in your application layout), is to use a callback which sets these variables each time:
#app/controllers/application_controller.rb
Class ApplicationController < ActionController::Base
before_action :set_vars
private
def set_vars
#food = Food.all
#food_type = FoodType.all
end
end
Although relatively inefficient (you'll be best caching this data so it won't be pinging your DB each time), you'll be able to use #food and #food_type in your application layout with no issues

Why my helpers does not outputting nothing in my view?

I'm new on rails and I have a book to study them. In one practice, I created a helper in my Application Helper, the test from RSpec work fine, until I have to print the result of my helper. No show any result and no error happens.
application_helper.rb
module ApplicationHelper
def title(*parts)
unless parts.empty?
content_for :title do
(parts << "Ticketee").join(" - ")
end
end
end
end
show.html.erb
<% title(#project.name) %>
projects_controller.rb
class ProjectsController < ApplicationController
def show
#project = Project.find(params[:id])
end
end
and when I go to the show link I supposed to see "Random Project name - Ticketee", however only they show me "Ticketee".
Any help...
<% title(#project.name) %>
Means don't show to the user
<%= title(#project.name) %>
Means show to the user - notice the equals.

Passing variables in RoR from html to model

I'm new to developing in Ruby on Rails and I'm stuck on a little project that I've been working on to understand RoR better. I am trying to make a little weather website and I'm having trouble sending user input to a model through a controller and to have that model use send back the correct information so that I can parse it and what not. I have not been able so far to send the user param along to the controller so that it will send out the right request. Here is my following code:
hourly.html.erb:
<%= form_tag('/show') do %>
<%= label_tag(:location, "Enter in your city name:") %>
<%= text_field_tag(:location) %>
<br />
<%= submit_tag "Check It Out!", class: 'btn btn-primary' %>
<% end %>
hourly_lookup_controller.rb:
class HourlyLookupController < ApplicationController
def show
#hourly_lookup = HourlyLookup.new(params[:location])
end
end
hourly_lookup.rb:
class HourlyLookup
def fetch_weather
HTTParty.get("http://api.wunderground.com/api/api-key/hourly/q/CA/#{:location}.xml")
end
def initialize
weather_hash = fetch_weather
assign_values(weather_hash)
end
def assign_values(weather_hash)
more code....
end
end
Any help or directions to some good examples or tutorials would be greatly appreciated. Thanks
If you want to send a variable to HourlyLookup, you'll need to do so:
class HourlyLookupController < ApplicationController
def show
#hourly_lookup = HourlyLookup.new(params[:location])
#hourly_lookup.fetch_weather
end
end
class HourlyLookup
attr_reader :location
def initialize(location)
#location = location
end
def fetch_weather
response = HTTParty.get("http://api.wunderground.com/api/cdb75d07a23ad227/hourly/q/CA/#{location}.xml")
parse_response(response)
end
def parse_response(response)
#parse the things
end
end

Multilevel block methods in rails

I am making a view helper to render set of data in a format. I made these classes
require 'app/data_list/helper'
module App
module DataList
autoload :Builder, 'app/data_list/builder'
##data_list_tag = :ol
##list_tag = :ul
end
end
ActionView::Base.send :include, App::DataList::Helper
helper is
module App
module DataList
module Helper
def data_list_for(object, html_options={}, &block)
builder = App::DataList::Builder
arr_content = []
object.each do |o|
arr_content << capture(builder.new(o, self), &block)
end
content_tag(:ol, arr_content.join(" ").html_safe, html_options).html_safe
end
end
end
end
builder is
require 'app/data_list/column'
module App
module DataList
class Builder
include App::DataList::Column
include ActionView::Helpers::TagHelper
include ActionView::Helpers::AssetTagHelper
attr_reader :object, :template
def initialize(object, template)
#object, #template = object, template
end
protected
def wrap_list_item(name, value, options, &block)
content_tag(:li, value).html_safe
end
end
end
end
column module is
module App
module DataList
module Column
def column(attribute_name, options={}, &block)
collection_block, block = block, nil if block_given?
puts attribute_name
value = if block
block
elsif #object.respond_to?(:"human_#{attribute_name}")
#object.send :"human_#{attribute_name}"
else
#object.send(attribute_name)
end
wrap_list_item(attribute_name, value, options, &collection_block)
end
end
end
end
Now i write code to test it
<%= data_list_for #contracts do |l| %>
<%= l.column :age %>
<%= l.column :contact do |c| %>
<%= c.column :phones %>
<% end %>
<%= l.column :company %>
<% end %>
Every thing is working fine , age , contact , company is working fine. But phones for the contact is not showing.
Does any one have an idea, i know i have missed something in the code. Looking for your help.
Updated question with complete source is enter link description here
There are two issues I can see in the column module.
1) If a block is provided you're setting it to nil - so if block is always returning false. 2) Even if block wasn't nil you're just returning the block as the value, not actually passing control to the block. You should be calling block.call or yielding. Implicit blocks execute faster, so I think your column module should look more like this:
module DataList
module Column
def column(attribute_name, options={})
value = begin
if block_given?
yield self.class.new(#object.send(attribute_name), #template)
elsif #object.respond_to?(:"human_#{attribute_name}")
#object.send :"human_#{attribute_name}"
else
#object.send(attribute_name)
end
end
wrap_list_item(attribute_name, value, options)
end
end
end
The solution is now posted in the discussion.

Resources