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
Related
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.
I'm seeing very strange behavior in Rails 3.2.20.
I created an example app with 2 simple models.
class Bro < ActiveRecord::Base
attr_accessible :cool_story
scope :hey_bro, -> do
where(nil)
end
end
class Dawg < ActiveRecord::Base
attr_accessible :where_you_at
end
From irb:
🐈 jonesdeini#scooty_puff_jr ~/example$ rails c
Loading development environment (Rails 3.2.20)
1.9.3-p125 :001 > Dawg.where(nil).respond_to? :hey_bro
=> false
1.9.3-p125 :002 > Bro.hey_bro
Bro Load (0.6ms) SELECT "bros".* FROM "bros"
=> []
1.9.3-p125 :003 > Dawg.where(nil).respond_to? :hey_bro
=> false
1.9.3-p125 :004 > Bro.where(nil).hey_bro
Bro Load (0.8ms) SELECT "bros".* FROM "bros"
=> []
1.9.3-p125 :005 > Dawg.where(nil).respond_to? :hey_bro
=> true
Can someone please explain what is going on here?
The complete code is here: https://github.com/jonesdeini/rails3.2-weirdness
Update:
The strangeness can be traced to here:
https://github.com/rails/rails/blob/v3.2.20/activerecord/lib/active_record/relation/delegation.rb#L26
super returns true after a scope has been added to a where. (probably better explained by the output in this gist https://gist.github.com/jonesdeini/dbe3124b2c31bd31ed31)
I seem to remember reading somewhere that rails won't commit to the database if no attributes have been changed (presumably as part of active record dirty) is this the case? I can't seem to find it and am none the wiser having had a quick look through the source code.
If this is false I need to use a before_save callback because I want to run some code based on whether or not a change has occured.
I assume after_save with dirty data won't work??
Rails won't do an UPDATE but it will run the after_save callbacks even if nothing has changed:
pry $ u = User.first
=> #<User id: 1, email: "dave#davebryand.com", username: "dbryand"...
pry $ u.updated_at
=> Tue, 24 Jun 2014 18:36:04 UTC +00:00
pry $ u.changed?
=> false
pry $ u.save
From: /Users/dave/Projects/sample/app/models/user.rb # line 3 :
1: class User < ActiveRecord::Base
2:
=> 3: after_save -> { binding.pry }
pry $ exit
=> true
pry $ u.updated_at
=> Tue, 24 Jun 2014 18:36:04 UTC +00:00
If you want to do something dependent on changes to a particular attribute in a before_save, just do:
pry $ u = User.first
=> #<User id: 1, email: "dave#davebryand.com", username: "dbryand"...
pry $ u.save
=> true
pry $ u.name = "John Doe"
=> "John Doe"
pry $ u.save
From: /Users/dave/Projects/sample/app/models/user.rb # line 3 :
1: class User < ActiveRecord::Base
2:
=> 3: before_save -> { binding.pry if name_changed? }
Dirty docs here: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
This is one of those ones that makes you think you're going insane...
I have a class Section, and a DraftSection that inherits from it:
(Trimmed for brevity)
class Section
include Mongoid::Document
belongs_to :site
field :name, type: String
end
And
class DraftSection < Section
field :name, type: String, default: "New Section"
end
All simple stuff... console proves (again, trimmed for brevity):
004 > site = Site.first
=> #<Site _id: initech, name: "INITECH">
005 > site.sections.build
=> #<Section _id: 1, site_id: "initech", name: nil>
006 > site.draft_sections.build
=> #<DraftSection _id: 2, site_id: "initech", name: "New Section">
As you can see - the draft section name correctly defaults to "New Section" as it is overridden in the subclass.
Now when I run this spec:
describe "#new" do
it "should return a draft section" do
get 'new', site_id: site.id, format: :json
assigns(:section).should == "Something..."
end
end
Which tests this controller method:
def new
#section = #site.draft_sections.build
respond_with #section
end
Which fails (as expected), but with this:
Failure/Error: assigns(:section).should == "Something..."
expected: "Something..."
got: #<DraftSection _id: 1, site_id: "site-name-4", name: nil> (using ==)
What gives???
Update:
I figured it might be an issue with the different environment settings, so I looked at the mongoid.yml config file and saw this in the options:
# Preload all models in development, needed when models use
# inheritance. (default: false)
preload_models: true
I added it to the test environment settings too, but still no joy :(
Update 2 - the plot thickens...
Thought I'd try loading up the console in the test environment and trying the same as before:
001 > site = Site.first
=> #<Site _id: initech, name: "INITECH">
002 > site.draft_sections.build
=> #<DraftSection _id: 1, site_id: "initech", name: "New Section">
WTF?
Ok, no one's listening, but I'll post the solution here for future reference anyway...
For some reason, some time ago I had a debug session that meant I had left this code in my Spork.each_run block
# Reload all model files when run each spec
# otherwise there might be out-of-date testing
# require 'rspec/rails'
Dir["#{Rails.root}/app/controllers//*.rb"].each do |controller|
load controller
end
Dir["#{Rails.root}/app/models//*.rb"].each do |model|
load model
end
Dir["#{Rails.root}/lib//*.rb"].each do |klass|
load klass
end
This was causing the models to get reloaded on each run of a spec. Not surprisingly, this screwed up the way the classes were set up in memory whilst the specs were running.
Definitely explains why it was such a hard one to debug...
So for future googlers with similar inheritance problems in Rspec only - make sure that there's nothing reloading models anywhere in the test stack.
How is this possible?
Loading development environment (Rails 2.3.8)
>> wq = Wq.first(:conditions =>['widget_id=? AND qs_id=?',1,1])
=> #<Wq id: 1, widget_id: 1, qs_id: 1, operator: 0, requirements: "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2", changes: "1", route: 2, created_at: "2010-09-07 08:11:05", updated_at: "2010-11-24 10:25:53", body: "Which specific area of gyt are you aiming to addres...", options: "['xyz','pqr']", input_type: nil, status: 1>
>> wq.changes
=> {}
>> wq.changes
=> {}
>> wq.requirements
=> "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2"
>> wq.changes
=> "1"
Why is wq.changes coming as null initially and then after logging wq.requirements, wq.changes seems to come fine?
All necessary fields that are being fetched are withing a attr_accessible in the model.
I am not able to understand this situation, please help all you rails gurus.
The attribute name 'changes' conflicts with the AR::Dirty functionality. You should probably pick a different name for that column.
Here's the rails3 api docs for Dirty:
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
In rails2 it's in ActiveRecord rather than ActiveModel.
If you aren't able to rename the column, you could work around the issue by calling #model_obj[:changes] instead.
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb#L1466