rails update question: where are the new files? - ruby-on-rails

Some time ago I updated my app from Rails 1.2 to 2.3. The upgrade definitely worked (was in pagination hell for a while), and the app has been working fine.
But now I'm in the process of upgrading my app for mobile use and want to use the Mobile Fu plugin. However, that calls for changing the mime_types.rb file... and I don't have that. In fact, I don't have the entire Initializers folder in my config folder, nor the locales folder.
How do I get these directories into my app? Are there other things I'm missing? And what did I do wrong in the upgrade process?
Thanks!

Running rake rails:update should have handled all the requirements of a Rails 2.3 app. Initializers are not a requirement -- they are a new convenience that was added. If you want the same default file structure as a new Rails 2.3 app, I recommend creating a dummy app and copying the initializer and environment files over so you're working with up-to-date templates.

Related

Rails 7 - autoloading fails for Rails engine RSpec tests with gem

I maintain https://rubygems.org/gems/scimitar. Yesterday, we wanted to upgrade our primary application to Rails 7. This required a corresponding upgrade of Scimitar.
Tests I think are quite straightforward for a Rails engine; you have a dummy Rails app inside your tests, which requires the gem code as usual (require 'scimitar' in application.rb, in this case) and then - well - I guess via the mount in the dummy app's routes.rb, or some other autoloading magic, it thereafter "just works". Classes that are defined in the engine's application components (e.g. /app/models/gemname/foo.rb -> Gemmname::Foo) are autoloaded and available in your dummy application (e.g. /spec/dummy/app/controllers/some_controller.rb can reference Gemname::Foo).
The test suite works fine in Rails 6. If I change the gemspec file to reference Rails 7 and bundle update, tests immediately all fail. None of the constants defined in the engine are visible to the dummy app and since they're referenced by a configuration file in spec/dummy/app/config/initializers/scimitar.rb, the dummy app can't even complete Ruby parsing without raising NameError (uninitialized constant). I also ran a Rails 7 upgrade on that dummy app, but it does kinda nothing and had almost no changes; there were no changes to observed behaviour (tests still failed) and the post-upgrade dummy app ran tests successfully with the gem on Rails 6.
So, it just fails to behave in a recognisably sensible way on Rails 7.
Ruby version is unchanged at 2.7.x (though I would have bump to 3.1 if the Rails 7 update had worked).
I cannot find anything about this in 6->7 upgrade docs; classic autoloader has never been used and there is no specification about it either way; config.load_defaults as 6.0 or 7.0 makes no difference at all; I tried creating a new engine plugin under Rails 7 to play spot-the-difference, but couldn't see what might be wrong and it was obfuscated somewhat since I'm using RSpec but the out-of-box template uses Minitest.
Can anyone please help explain what is going on here?
As it stands in Rails 7.0.1, I found no solution so had to hack around it. Anyone using the Scimitar gem would need to wrap their initializer code (config/initializers/scimitar.rb) with:
Rails.application.config.to_prepare do
...
end
https://api.rubyonrails.org/classes/ActiveSupport/Reloader.html#method-c-to_prepare
Doing this inside the Gem's own engine initializer code and the dummy app initializer code allowed the test suite to run. Likewise, there were quite a few places in our main Rails application beyond just Scimitar that suddenly required this workaround, including some examples of just plain old Ruby gems.

Upgrading Rails: What am I to do with new_framework_defaults file?

I am upgrading from rails 5.1 to 5.2.
I did bundle update rails (plus some dependencies) and rails app:update.
Now i have the file initializers/new_framework_defaults_5_2.rb, with all lines are commented out.
I am not sure what I need to do now. My app works normally, so I guess, with all lines are commented out I am already on all new defaults. Then I do not need that file, right?
Suppose I run into errors, the values set in the files are the new defaults? So I would uncomment, maybe flip the boolean and try to find out what caused the error?
thank you for your help
(Having just gone through a 4.2 to 5.2 Rails upgrade, I'll write a more complete answer.)
Rails 5.0
Starting with Rails 5, the Rails team decided to generate an initializer, config/initializers/new_framework_defaults.rb, that contained values for new configuration defaults. This file is generated for both new (rails new) Rails 5.0 applications and applications updated (rake app:update) to Rails 5.0, although the contents differ between new and updated apps.
For new projects, it contains defaults for Rails 5.0.
For updated projects, it contains defaults for the previous version. The intent is that your application will run with the same defaults it had before, and you can toggle/update one at a time during your upgrade.
Rails 5.1 and 5.2
After some shortcomings of this mechanism became apparent (mostly related to the execution of initializers in lexical order), Rails 5.1 made some changes to it.
A new method, #load_defaults, has been added to Rails.application.config. The new framework defaults initializer is versioned, e.g., new_framework_defaults_5_1.rb, and it is only generated during an update, not for a new application.
Unlike the new_framework_defaults.rb from Rails 5.0, settings in the new_framework_defaults_5_x.rb files are (almost) all commented-out. They are the new defaults. You can go through each of them, uncomment the setting, and test your application. If your application runs correctly on the new defaults, you can discard the new_framework_defaults_5_x.rb file and bump the value in config/application.rb to the current version, i.e., change config.load_defaults 5.1 to config.load_defaults 5.2 if you were updating to Rails 5.2.
It's possible there is a setting for which you don't want the new default. If I wanted to make such a setting permanent, I'd probably move it into config/application.rb somewhere below the load_defaults call for all environments, or in the appropriate config/environments/*.rb file(s) for environment-specific configurations.
Summary
It seems to me like the config/initializers/new_framework_defaults*.rb files should not exist after successfully completing an upgrade. They're just there to help highlight changes and aid upgrading from one version to the next.

Rails caching my code after upgrading to Ruby 2.0 on Mac OS X Mountain Lion

Rails 3.2.13 is caching my helper modules, controllers, and other ruby code in Development mode after upgrading to Ruby 2.0 from Ruby 1.8.7 on Mac OS X Mountain Lion 10.8.4
The code changes are only picked up after I restart the server every time even in the rails console. The reload! command in the console also does not work and does not reload my code changes until I restart the rails console again.
The Javascript and Sass files are not cached but the Views, Controller and other ruby code is. I checked the development.rb file and the following cache setting is set to false.
config.cache_classes = false
Also when starting the server it starts in development mode as seen on the console log
Rails 3.2.13 application starting in development on http://0.0.0.0:3000
Not sure what happened but I did change the timezone and time of my system for testing purposes and reverted the time back to the actual time.
I have even git cloned the repo again onto my system after restarting my machine with the correct time and timezone and still have the issue. Does anyone know how to fix this or how to force reload all the ruby code everytime the request is made in development mode?
If you also upgraded recently from an older Rails version. If that is the case, note that lib is not autoloaded in Rails 3. You are talking about helper modules and controllers which should still be autoloaded, but lib won't be. You can change it to be autoloaded as noted in this answer, add another autoloaded dir, or move those classes until an existing autoloaded directory (e.g. app/models, if that is appropriate).
If you have stuff configured in config.autoload_once_paths then that could be a problem for reloading those, otherwise they should be reloaded per request per the guide (and you can look at the code here if you're curious about what is going on).
Also, check to make sure you are really running in development mode and note that you can't add lib to config.eager_load_paths in development.rb per this answer.
If you had time issues with the code, also maybe when you recloned the repo, you are still getting the wrong dates on the files. Try doing: find /path/to/rails/app -exec touch {} \; to update the file mod datetimes. (Also as an aside, you might want to be sure that the datetimes in your DB in created_at/updated_at are ok. Hopefully that isn't a problem, because that could be a mess.)
Finally, be sure that classes that are under the autoloaded directory correspond to the modules that they are in. For example Foo::BarsController could be in app\controllers\foo\bars_controller.rb but not in app\controllers\bars_controller.rb if you want it to be able to be autoloaded and reloaded properly.

Is there a way for a ruby on rails app to support web-based upgrades like Wordpress does?

I've been using Wordpress for awhile, it's installed on my own server, and one of the features I most love about it is how every time there is a new version it alerts you within the app's web-based admin and with one click I can upgrade the app. I don't have to get anywhere near a console.
Personally I wouldn't mind updating manually, but I can see how this could significantly affect the adoption of a piece of software. I'm working on creating a full-featured ruby on rails forum software and I would love to figure out how to include this feature. Any ideas if this could be done with rails?
Could a rails app modify it's own files? If it did, would the server need to be restarted?
To complicate things further, what if the app was deployed from a repo. Could the rails app check in a commit of itself after updating?
Maybe packaging the core of the app as a gem would be simpler? Then maybe the upgrade would not actually modify the rails MVC stack (the rails app would just be super-basic), instead if the forum was all contained within a gem then all it has to do is trigger a 'gem update [name]'. If this occurred, I don't think the Gemfile would even need to be updated. Would a server restart even be required to load the updated gem?
Ideas or feedback on any of this?
Rails files can be modified and even deleted on production - in my case aplication is still working unchanged as all classes are cached in memory. It means Rails instances must be restarted to take new change.
I suppose WordPress is Perl via CGI and you just drop application into web directory to have it working immediately - same with updates - just overwrite files and Apache picks them up immediately.
In case of Rails is that you don't know target deployment architecture thus restarting application may not be trivial. E.g. with passenger I can just do touch tmp\restart.txt and then all instances are killed and started again. Some deployments may need init.d script restart invocation.
Maybe you could recommend or prepare a ready to use deployment model which supports autoupdate. In other cases users could do updates manually.

Running Rails as an embedded app inside of a gem

I'm trying to understand what exactly the above (in my question's Title) means? This is taken directly from the SpreeCommerce.com project:
If you’re an experienced Rails developer you may be wondering where your app directory is. Spree actually runs as an embedded Rails app inside of your gem. How do you customize things then? We’ll cover that later in extensions.
Source: http://spreecommerce.com/documentation/getting_started.html
Can someone further explain what exactly it means when a Rails app is run "inside of your gem"
With the gem spree, you can install your application and use it. A lot of application need download complete package to install it. When the gem spree, you don't. So it's more easier to install spree on your server.
The phrase you quote is poorly written and not particularly useful. What you should take away is that Spree is structured different from the majority of Rails plugins.
Typical plugin:
your rails app <-- plugin functionality
A Spree app:
spree rails app <-- your site specific code
Typically, most Rails plugins are installed in the vendor/plugins directory of your Rails app. Some additional functionality is added by classes and modules that you can then reference in your code (subclassing a ResourceController, for instance).
Spree does not work in this way. Because, presumably, there is so much configuration code for Spree, each Spree instance creates a separate Rails app -- one that's missing some of the more important parts of a Rails app (such as the app directory). All of your site specific code goes in the vendor/extensions/site directory. This means you don't have to worry about editing any of the Spree-specific code (since it's all in a different directory) and you can more easily put your own code under source control.

Resources