rspec test fails code in rails controller - ruby-on-rails

In my application_controller.rb, i have a line of code as follows:
def index
CaseStatus.order(:application_source).pluck(:application_source).uniq!
end
In my rspec code, i have a line of code that visits the index path of application_controller as follows
visit applications_path
When i run the code directly, it works perfectly but when it visits application_controller.rb via rspec, i get an error which says
NoMethodError:
undefined method `compact' for nil:NilClass
Not sure while i get this error via rspec and capybara but if i run the code as
def index
CaseStatus.order(:application_source).pluck(:application_source)
end
It executes perfectly with no errors. Kinda confused what the uniq! breaks in the code that suddenly the result becomes nil.
i get this error
Failure/Error: #application_channels = CaseStatus.order(:application_source).pluck(:application_source).uniq!.compact if CaseStatus.order(:application_source).present?
NoMethodError:
undefined method `compact' for nil:NilClass
# ./app/controllers/loan_applications_controller.rb:53:in `index'

I do not think uniq! is the method you would like to use in this case, see:
Returns nil if no changes are made (that is, no duplicates are found).
https://ruby-doc.org/core-2.2.0/Array.html#method-i-uniq-21
So it works like this:
2.3.1 :008 > a = [1,2,3,3,nil].uniq!
=> [1, 2, 3, nil]
2.3.1 :009 > a = [1,2,3,nil].uniq!
=> nil
2.3.1 :010 >
on the other hand uniq works like:
2.3.1 :010 > a = [1,2,3,3,nil].uniq
=> [1, 2, 3, nil]
2.3.1 :011 > a = [1,2,3,nil].uniq
=> [1, 2, 3, nil]
and on the output of uniq it is safe to run compact to remove nil values.

Related

Getting undefined method in Controller yet method exists and works in Rails console

I am attempting to build a simple web app that takes data passed in to a text field and delivers it to an API. I have created a model with some methods to do some basic calls to the API. I have set up a form with a text field and a submit button to pass along the data to a controller. When I submit I am getting an error that the method I am calling is not defined. Yet if I go in the console and try the same thing it works as expected. Any suggestions on what I am missing?
Model:
def update(serial, deploy_value)
HTTParty.post("#{BASE_URL}devices/update/serial/#{serial}?#{API_KEY}",
:body => {"customFieldValues": [{"name": "Deploy","value": "#{deploy_value}"}] }.to_json,
:headers => { 'Content-Type' => 'application/json'}
)
end
Controller
class GroundControlController < ApplicationController
require 'GroundControl'
def update
serial = params[:serial]
GroundControl.new.update(serial, "TEST")
redirect_to(:back)
end
end
The error I am getting:
NoMethodError in GroundControlController#update
undefined method `update' for GroundControl:0x007fa062aa1298
From the console I can do the following:
2.3.0 :002 > require 'GroundControl'
=> true
2.3.0 :003 > test = GroundControl.new
=> #<GroundControl:0x007fa2676a8838>
2.3.0 :004 > GroundControl.new.update("ABC123", "TEST")
=> #<HTTParty::Response:0x7fa2671fb218 parsed_response={"id"=>43270, "serial"=>"ABC123", "udid"=>nil, "name"=>nil, "model"=>nil, "os"=>nil, "connected"=>false, "customFieldValues"=>[{"name"=>"Deploy", "value"=>"TEST"}]}, #response=#<Net::HTTPOK 200 OK readbody=true>, #headers={"server"=>["nginx/1.6.3"], "date"=>["Tue, 12 Apr 2016 15:09:27 GMT"], "content-type"=>["application/json; charset=utf-8"], "content-length"=>["150"], "connection"=>["close"], "access-control-allow-origin"=>["*"]}>
2.3.0 :005 >
More info on the error I am getting:
NoMethodError in GroundControlController#update
undefined method `update' for #
Extracted source (around line #10):
8 def update
9 serial = params[:serial]
10 GroundControl.new.update(serial, "TEST")
11 redirect_to(:back)
12
13 end

Why does subclassing ActiveSupport::TimeZone break its class-level [] operator?

With some trepidation, I decided to subclass ActiveSupport::TimeZone, but I can't get very far because when I call [] on my subclass it fails to invoke the superclass's [] method. I thought it might have had something to with the fact that the operator overload happens in a class method, so I tried this:
Loading development environment (Rails 4.2.1)
2.2.1 :001 > class Foo; def Foo.[](f); f; end; end
=> :[]
2.2.1 :002 > Foo['baz']
=> "baz"
2.2.1 :003 > class Bar < Foo; end
=> nil
2.2.1 :004 > Bar['baz']
=> "baz"
So that worked exactly as I thought it would. But if that works, why does this fail?
2.2.1 :005 > ActiveSupport::TimeZone["America/New_York"]
=> #<ActiveSupport::TimeZone:0x007f80835c18a8 #name="America/New_York", #utc_offset=nil, #tzinfo=#<TZInfo::TimezoneProxy: America/New_York>, #current_period=#<TZInfo::TimezonePeriod: #<TZInfo::TimezoneTransitionDefinition: #<TZInfo::TimeOrDateTime: 1425798000>,#<TZInfo::TimezoneOffset: -18000,3600,EDT>>,#<TZInfo::TimezoneTransitionDefinition: #<TZInfo::TimeOrDateTime: 1446357600>,#<TZInfo::TimezoneOffset: -18000,0,EST>>>>
2.2.1 :006 > class T < ActiveSupport::TimeZone; end
=> nil
2.2.1 :007 > T["America/New_York"]
NoMethodError: undefined method `[]' for nil:NilClass
The method relies on calling [] on an #lazy_zones_map instance variable, which your subclass does not have.
Edit: an example of the behavior:
class Foo
#foo = []
def self.[](arg)
#foo[arg]
end
end
class Bar < Foo
end
Foo[0] #=> nil
Bar[0] #=> undefined method `[]` for nil:NilClass

Rails: Restarting the server each time make change in code using console

I am using accessing my controllers methods from console with rails c command. The problem I am facing is that each time I have reflect any changes made in the code then I have to first exit and restart . Is these any way to fix this problem?
From your rails console, type reload!
2.1.2 :012 > reload!
Reloading...
=> true
2.1.2 :013 >
to reload all your Rails application code. No need to exit and start console again!
If you have associations you can do this:
class home
belongs_to :renter
end
class renter
has_one :home
end
Let's say you start with home attributes:
home = Home.where(renter_id: 1)
=> #< Home id: 1, alarm: "no">
renter = Renter.find(1)
renter.home.alarm
=> "no"
Then you modify home:
home.alarm = "yes"
home.save
When you do:
renter.home
=> #< Home id: 1, alarm: "no"> # it still returns no
renter.home(true)
=> #< Home id: 1, alarm: "yes">"
# you can use (true) to make sure your association
# change is reflected, it basically queries the server again

How can I load UrlHelper and the routes in the Rails?

I want to include the routes and the link_to method in a PORO. While testing this in the console I came accross this:
If I include UrlHelper without the routes helper everything seems to work fine:
ruby-1.9.3-rc1 :001 > Rails.version
=> "3.2.0.rc2"
ruby-1.9.3-rc1 :001 > include ActionView::Helpers::UrlHelper
=> Object
ruby-1.9.3-rc1 :002 > link_to "foo", Rails.application.routes.url_helpers.ponies_path
=> "foo"
If I include the routes:
ruby-1.9.3-rc1 :001 > include ActionView::Helpers::UrlHelper
ruby-1.9.3-rc1 :003 > include Rails.application.routes.url_helpers
=> Object
ruby-1.9.3-rc1 :004 > link_to "foo", ponies_path
I get the following error:
NameError: undefined local variable or method `controller' for #<ApplicationController:0x007fa1497ecc40>
What am I doing wrong here?
As suggested you should use the app object for the routes part and you should be using the helper object for the link_to.
No need to include any of the helpers through Ruby when using the console:
helper.link_to "foo", app.ponies_path
Use the app object.
> link_to "foo", app.ponies_path

opening Array in ruby on rails console v. irb

I wish to make my code a little more readable by calling #rando on any array and retrieve a random element (rando because a rand() method already exists and I don't want there to be any confusion).
So I opened up the class and wrote a method:
class Array
def rando
self[ rand(length) ]
end
end
This seems far too straightforward.
When I open up irb, and type arr = %w(hi bye) and then arr.rando I get either hi or bye back. That's expected. However, in my rails console, when I do the same thing, I get ArgumentError: wrong number of arguments (1 for 0)
I've been tracing Array up the rails chain and can't figure it out. Any idea?
FWIW, I'm using rails 2.3.11 and ruby 1.8.7
Works fine in my case :
Loading development environment (Rails 3.0.3)
ruby-1.9.2-p180 :001 > class Array
ruby-1.9.2-p180 :002?> def rando
ruby-1.9.2-p180 :003?> self[ rand(length) ]
ruby-1.9.2-p180 :004?> end
ruby-1.9.2-p180 :005?> end
=> nil
ruby-1.9.2-p180 :006 > arr = %w(hi bye)
=> ["hi", "bye"]
ruby-1.9.2-p180 :007 > arr.rando
=> "bye"

Resources