I tried upgrading my rails app from rails 4.1.0 => 4.2.7 but found that it broke my JSON views. In particular, ActiveRecord objects no longer render correctly.
For instance: Model.first.to_json in rails console now produces "#\u003cModel:0x007f9208c904e0\u003e", rather than valid JSON as before. Model.first.as_json works correctly, but for some reason, it seems to_json is calling to_s instead.
I tried overriding the ActiveSupport encoder but it didn't help, and am pretty stumped.
Any ideas?
(UPDATE: I also noticed Time.now.utc.to_json changed from 2017-12-07T19:38:47Z => 2017-12-07 19:37:55 UTC, the latter being == time.as_json and the former == time.to_s)
Related
I've recently done an rails and ruby upgrade, we don't have strong params in the app (I know it's legacy).
So the way it's done in the app we have the following
def all_params_permitted(this_params = nil)
this_params = params if this_params == nil
this_params.permit!
this_params.each do |i, v|
if v.kind_in?([Hash, ActionController::Parameters])
all_params_permitted(v)
end
end
end
Which loops through all params and just accepts everything, all_params_permitted is called throughout the app I would love to add strong params but that's a no-go for now.
The issue in the above method is kind_in? the upgrade I did for this app was rails 5.0.3 to rails 6.1+ and went from ruby 2.2.6 to ruby 3.0.1 so I'm not sure why kind_in? has stopped working. This is an old app (built-in rails 2) so not sure if this has been deprecated.
Any help here would be great.
Edit
I have tried kind_of? but no dice.
the upgrade I did for this app was rails 5.0.3 to rails 6.1+ and went from ruby 2.2.6 to ruby 3.0.1
This is asking for trouble. It is strongly advised to try upgrading one minor version at a time (e.g. rails 5.0 --> 5.1 --> 5.2 --> 6.0 --> 6.1), otherwise you're very likely to break things with little information on why it's stopped working/how to fix it.
Likewise for ruby versions... At an absolute minimum I'd postpone the final upgrade to ruby v3 until your application works fine under ruby 2.7.
I'm not sure why kind_in? has stopped working
Nor am I, because that's a custom method. You haven't show us how it's defined, and nor have you shown us the error message, so it's impossible for me to say with confidence what's gone wrong.
My guess is that it's implemented something like this:
class Object
def kind_in?(classes)
classes.any? { |c| self.kind_of?(c) }
end
end
i.e. it's a little wrapper around the built-in kind_of? method.
And with that said, I still have no idea why this would have "stopped working" due to a ruby and/or rails upgrade.
Not sure about kind_in?, also didn't find any reference to that method, also as you have not posted the error so not sure about your issue. is_a?, kind_of?, instance_of? are few methods that check the object class but they check only a single class. Looking at your code one option for your condition could be:
if [Hash, ActionController::Parameters].include?(v.class)
which will check if it belongs to one of these classes.
I am trying to upgrade my rails 3.0.5 application with ruby 2.3.4. Originally it was ruby 1.9.3. I was able to fix most things by updating the gems. However, i m stuck on this one problem where when creating new active record objects, the time does not convert properly.
For example
Product.new(:bought_on => Date.today) will save the object with bought_on to be the date, not datetime.
I was able to narrow down the problem to the file
activerecord-3.0.20/lib/active_record/attribute_methods/time_zone_conversion.rb
For some reason its not calling these two functions, define_method_attribute and define_method_attribute=.
Any ideas?
I found the issue, the define_method_attribute under time_zone_conversion.rb is a protected method, and in ruby 2, the respond_to function always returns false for protected methods. Had to monkey patch to remove the protected attribute.
I use the following code in one of my models
def jasper_amount
ActionController::Base.helpers.number_to_currency(amount)
end
I know that it breaks MVC. However, in this case it is the best solution. I have to pass data to Jasper via the Ruby Java Bridge and formatting in Jasper would be much more complicated.
Calling object.jasper_amount from the rails console works fine and prints the expected results. This works fine in development and production.
Now, to pass the data to Jasper I first have to create an xml version of the object's attributes using object.to_xml(methods: [:jasper_amount]).to_s This works in development but not in production. In production the value for jasper_amount that is passed to Jasper is "0.00 €". However, if I remove number_to_currency from def jasper_amount (just returning unformatted amount) it works. What's even more confusing is the fact that calling jasper_amount from the rails console in productions works. I guess the culprit must be to_xml, but I have no idea why it works in development and not in production.
The problem was with Ruby Java Bridge (rjb) and BigDecimal. If you use BigDecimal with rjb, you have to include the "BigDecimal" gem in your Gemfile. Otherwise all your BigDecimals will be 0 (and that all over your app!)
When i am trying to upgrade Rails to 2.3.16 from 2.3.15, the ActiveSupport::JSON.decode(response.body) fails to handle NaN.
Am getting an error like: invalid character at "NaN,...
Does anyone know how to fix it?
ActiveSupport::JSON.decode uses MultiJson under the hood which tends to ignore any passed in options (At least in Rails 3, not sure about 2.3). This means you can't pass in the usually accepted option of allow_nan.
However, if you are using Ruby 1.9+ you can use the built-in JSON parser:
require 'json'
json_result = JSON.parse(response.body, allow_nan: true)
I recently upgraded by current app to Rails 3.2.8 and can't get a few tests to pass. I made a helper method that merges certain hashes with the params hash and creates a link to the current page. I used technique I saw on: link_to the current page plus/merged with a param.
Here is a stripped down version:
def simple_link
link_to "Page", params.merge(:c => nil)
end
Then I would test it with something like:
describe "simple_link" do
it { simple_link.should == "Page" }
end
Which was passing in 3.2.6.
However, now I receive the rspec error No route matches {:c=>nil}. Either Rails, rspec, or capybara is thinking the hash is the route. If I add a proper route like: users_path, then url_for seems to pick up the hash. Testing on a browser, everything works fine, no errors. Am I doing something wrong, was something changed in 3.2.8 or is this a bug?
Upgrading rails also upgrades the journey routing gem from 1.0.3 to 1.0.4. In that upgrade, there was a change to how routing treats constraints:
1.0.4 fixed a regression from Rails 3.1 where the router would return a route even if the constraints a user passed in didn't match anything.
Since you mention (in the comments) that downgrading journey to 1.0.3 fixes the problem, this change in journey is almost certainly the cause of the problem. Have a look at these github issues to find possible solutions:
1.0.3 -> 1.0.4 update breaks url_for in tests
ActionController::RoutingError in controller specs
The error is the way I'm calling link_to from a helper and not providing a current request. For now, I can get around the error by stubbing url_for, but this does not allow me to test the params hash. So trying to find a better way.
it "should return the right tag" do
self.stub!(:url_for).and_return '/bar'
simple_link.should == "Page"
end