Toggle! Bang Change in Rails 4 - ruby-on-rails-4

Trying to solve a mystery for the purpose of documentation.
We're upgrading from Rails 3.2 to Rails 4.
In the Rails 3.2 code, we have (well, had):
def update_object_special_eligibility
object.toggle!(:can_run_on_special) if object && object.can_run_on_special? && ineligible_for_special?
end
I realize this doesn't give you all the information you need, but here is the error. You should know that can_run_on_special is a bitfield rather than an official attribute, though I don't think it's actually relevant. Just thought I'd let you know why we were getting the error:
1) Error:
ObjectStatusTest#test_should_mark_object_as_not_eligible_to_run_on_special_for_specific_unschedule_reasons:
ActiveModel::MissingAttributeError: can't write unknown attribute `can_run_on_special'
config/initializers/acts_as_audited.rb:280:in `write_attribute_with_audit'
app/models/object_status.rb:437:in `update_deal_amazon_eligibility'
test/unit/object_status_test.rb:481:in `block in <class:ObjectStatusTest>'
test/fast_test_helper.rb:99:in `call'
test/fast_test_helper.rb:99:in `block in <class:TestCase>'
The code we changed it to that works on Rails 4:
def update_object_special_eligibility
if object && object.can_run_on_special? && ineligible_for_special?
object.update_attributes! :can_run_on_special => false
end
My suspicion is that because toggle! operates like update_attribute in terms of bypassing validations that it's just returning false for saving the attribute, and therefore, toggle! just doesn't work anymore because the updating of the attribute and the saving isn't working. But I am not sure that's the case. I'm hoping someone out here might have some idea about why this ActiveRecord::Persistence method (toggle!) might be operating differently in Rails 4. Or, is it the updating of the "attribute" and saving that is likely operating differently?
Thanks so much!

Looks like acts_as_audited is getting in on the act, and isn't bitfield/toggle savvy, would be my guess. Too many cooks hacking in their wares here. (bitfield and acts_as_audited).

Related

Why is ActiveRecord creating different ruby object when querying the same record?

I'm trying to test a named scope in my Rails model with RSpec using FactoryBot. I'm creating several records, where only one is returned by the scope.
RSpec.describe GemNamespace::GemModel, type: :model do
before(:all)
FactoryBot.create(:gem_model, :trait1) # id 1
FactoryBot.create(:gem_model, :trait2) # id 2
FactoryBot.create(:gem_model, :trait3) # id 3
end
let(:included_record) { GemNamespace::GemModel.find 1 }
describe 'my_named_scope' do
it 'returns only records matching the conditions' do
scope_results = GemNamespace::GemModel.my_named_scope
expect(scope_results).to contain_exactly(included_record)
end
end
end
The test is failing because even though included_record is the only record in the scope_results, some debugging shows that the included_record is actually a different Ruby object than the one in the results for some reason. Thus, the contain_exactly fails.
I've done scope testing like this on tons of models and it's always worked. The only difference with this one is that the model is defined inside a gem, and I'm extending its functionality by adding my named scope to it in my Rails app.
What am I missing? Why is it behaving like this only for this model?
If it matters:
Ruby 2.5.0
Rails 5.1.5
rspec 3.7.0
rspec-rails 3.7.2
factory_bot(_rails) 4.8.2
UPDATE: I'll put this here instead of editing the above. I am actually testing a database view as opposed to a table. The views do not have a unique id column, so I'm not actually doing a GemNamespace::GemModel.find 1 above, but instead a where(column: <condition value>).
I solved this with a workaround. I don't know too much about the internals of Rails, but it seems that the database view (and corresponding model) not having an id column kinda screws things up (i.e., the separate Ruby objects being created). So I simply compared all the values of the two objects "manually"
# As a workaround, we're just gonna convert them both to Ruby hashes using
# the #as_json method, and compare those instead.
expect(scope_results.as_json).to contain_exactly(included_record.as_json)

ActiveModel::MissingAttributeError (can't write unknown attribute `price_cents`): error after rails upgrading to rail 5.1

I have upgraded my rails app which was earlier on rails 4.1 to rails 5.1.
Now I am getting an error while using acts_as_shopping_cart gem, which is on version 0.4.1
I tried many things but not sure why exactly I am getting this error, while adding item to cart
ActiveModel::MissingAttributeError (can't write unknown attribute price_cents):
app/models/shopping_cart.rb:11:in add
app/controllers/shopping_carts_controller.rb:38:in add_to_cart
Any suggestions on this, will be appreciated. Thanks in advance
this one is still not yet supported for Rails 5 https://github.com/crowdint/acts_as_shopping_cart, you could try this one https://github.com/dabit/acts_as_shopping_cart
Late reply, but I was banging my head on this one for too long so I thought this may help other people.
You're getting the MissingAttributeError because your shopping_carts table doesn't have a price_cents field. The previous version of acts_as_shopping_cart (~ 0.2.2) was setup to use a float field called price, and it did not use the money-rails gem. The newer versions (>= 0.4.0) use money-rails and an integer field called price_cents, then money-rails "automagically" creates a attribute called "price" that converts to/from the price_cents field.
You may be able to migrate your price field using one of their helpers:
https://github.com/RubyMoney/money-rails#migration-helpers

Auto-generated rspecs

I am working on an existing RoR app which was written a few years ago. It's testers were less than satisfying so the whole /spec directory was removed and I have to write new rspecs. I have seen somewhere that it is possible to generate non-blank rspecs using scaffold method. When I tried doing
rails generate scaffold rspec:model User
I got the lovely result of
invoke active_record
/home/guy/railsProjects/netAdmin/vendor/ruby/2.0.0/gems/railties-4.1.6/lib/rails/generators/base.rb:258:in `const_defined?': wrong constant name Rspec:model (NameError)
from /home/guy/railsProjects/netAdmin/vendor/ruby/2.0.0/gems/railties-4.1.6/lib/rails/generators/base.rb:258:in `block in class_collisions'
how do I work it out? having something that will write some of the specs, based on the existing models and controllers will save me tons of time.
Thanks in advance!

Mongoid 4 finding embedded documents by ID

I have a project that is my first serious dive into Mongoid.
I saw a tip to use the following command:
Parent.where('childrens._id' => Moped::BSON::ObjectId(params[:id])).first
But this doesn't work. Error message was:
NameError: uninitialized constant Moped::BSON
I found that BSON is no longer included, so I added it to my Gemfile, as well as Moped. Then, I did another fix I found (placing Moped::BSON=BSON in application.rb).
This still didn't work, but the error changed to:
NoMethodError: undefined method `ObjectId' for BSON:Module
So I am assuming that this method got deprecated or something. Does anyone have any other tips?
Just to be clear, I am finding myself in the situation where I want to sort embedded documents using jquery-sortable. This requires me to update them in the database, but the serialize from that doesn't include the parent document in the hash. So I figured I'd try to get it on the back end using an ID from the embedded document. That is why I need it.
Thanks again for any help you can provide.
Try simply:
Parent.where('childrens._id' => params[:id]).first
I have solved the question though this won't be of much help to people in the future. The requirements have changed and now I am using human-readable strings as IDs to assist in friendly URLs and some other stuff.
Therefore, I don't have any issues with ObjectIds. Cortex's solution should (from what I have read) work for dealing with ObjectIds but I cannot verify it now.

Anyone using JRuby-Rack with Rails 3?

Is anyone else out there running Rails 3 and JRuby-Rack, or Jetty and Rails 3? Any trick to it? I'm going insane with some debugging, and at this point I just want to know that it's possible.
These instructions work for me:
http://mathias-biilmann.net/2010/2/jruby-and-rails-3-beta-step-by-step
i am using jetty-rails + rails3 for a couple of projects. jetty-rails need to be fixed , require "activesupport" need to be changed to require "active_support" (for activesupport 3.0.3) and you have also do 'require "active_support/all"' to include hash extensions (otherwise symbolize! & reverse_merge method will raise exceptions.. right now trying to fix some jruby-rack issues.. (Rack::Runtime not loaded)..will update once thats done.