Ruby on Rails
Rails 3 in Fedora 15
Submitted by mmorsi on Mon, 2011-02-07 17:12
To make use of the Rails RPMs from an earlier release, simply setup the rawhide repo and install rails:
* sudo yum install fedora-release-rawhide
* sudo yum install --enablerepo=rawhide rubygem-rails
Enjoy!
- mmorsi's blog
- Login to post comments
- Read more
Rails 2 -> 3 Case Study: Deltacloud
Submitted by mmorsi on Fri, 2010-12-17 03:26
Over the last few days I spent a little while updating Deltacloud from Rails 2 -> 3. The patchset is largely done, our application itself is fully functional, as is the spec suite, though there is a little more to do concerning getting some of our cucumber tests back to a functional state.
The upgrade process itself was fairly straightforward, I started off by creating a new project, then went through the newly created sources, copying the ones over which I could as is, merging the ones that affected files which we've changed. Overall the process is simple, though there were a bunch of nits involving doing things the new way and getting around deprecation warnings and such.
I'm also glad to say that all the upstream communities which develop and support gems we depend on seem to be on the ball, and while the rpms in Fedora need to be updated, the upstream gems all already support Rails 3. Authlogic is a small exception as it does work w/ Rails 3 but using it results in many ugly deprecation warnings in the logs. To get around these, I had to make the following changes to the authlogic gem itself (all files changes are in /usr/lib/ruby/gems/1.8/gems/authlogic-2.1.6/)
- lib/authlogic/session/callbacks.rb: s/save_without_session_maintenance(false)/save_without_session_maintenance(:validate => false)
- lib/authlogic/acts_as_authentic/password.rb: s/save(false)/save(:validate => false)
- lib/authlogic/acts_as_authentic/logged_in_status.rb: s/named_scope/scope
All in all here are the following changes that had to be made to our application to make it Rails 3 compliant:
-
Framework Changes (taken care of when you create a new rails 3 project):
- new versions of the public/*.html and public/dispatch* files
- all scripts have been placed with script/rails
- prototype.js, rails.js, and other javascripts have been updated
- Bundler is now being used to manage dependencies, remove gems from environment.rb (and specific environments/* config files) and move into Gemfile and Gemfile.lock
- Alot of the configuration api has been updated and you will need to change the various files in config/ to reflect this
- The Routing API has been overhauled, config/routes.rb will need some significant changes, but the nice thing is you can verify your routes w/ 'rake routes'
-
Application Changes:
- "filter_parameter_logging" is now being taken care of in the configuration
- "master_helper_module.module_eval" has been replaced by "class_eval" and "helper_method"
- "log_error" is no longer supported, replaced w/ the rails logger
- "request.request_uri" has been replaced w/ "request.fullpath"
- "before_filter" no longer takes an array, rather it just needs to be called multiple times
- I had to change "dispatch" in our templates controller to "dispatch_action" as the former was conflicting with a method added to all the controllers by rspec
- "WillPaginate::LinkRender" is now "WillPaginate::ViewHelpers::LinkRenderer"
- "named_scope" is deprecated, now simply use "scope"
- overriding the "validate" method is now deprecated, rather custom validation methods need to be registered
- "RAILS_ROOT" has now been replaced w/ "::Rails.root.to_s"
- In haml, the "-" operator has been deprecated, rather everything is now handled by "=" whether it outputs anything or not
- form.error_messages_on no longer simply just take text to prepend but rather a hash of which text to prepend/append/etc
-
Test Changes:
- Various changes to paths and urls to work w/ the new routing api
- The cucumber and rspec rake tasks have been updated
- All the specs need to "include Authlogic::TestCase" to make use of authlogic
- The "route_for" test helper has been replaced w/ 'route_to'
- The activerecord 'destroy' method no longer returns false, but an empty array (at least from my findings)
- Mock('foo', :null_object => true) has been replaced with mock('foo').as_null_object
- Activerecord errors do not support the 'on' method anymore (at least its deprected) rather you can access errors on specific fields by passing that field name as a hash key, which will return an array of errors
For reference here is the patchset updating Deltacloud to Rails 3. I can't push the changes to our codebase until Rails 3 is in Fedora with all the gems that depend on it, but the tentative goal is to do so by Fedora 15 (we have done some preliminary work to update the rpms on this front, but there is still a ways to go, help is always appreciated).
- Intro
- Rails 2->3 framework changes, nothing specific to deltacloud
- prototype.js and rails.js updates, also 100% rails, nothing specific to deltacloud, but large enough to justify their own patch
- gem dependency changes, introduces Gemfile for bundler
- deltacloud rails 3 config changes
- deltacloud rails 3 application changes
- deltacloud rails 3 views changes
- deltacloud rails 3 spec/cucumber changes
- misc changes
Hope this helps anyone looking to upgrade. It is a bit of a process, but the new Rails 3 changes are nice and look like they make more things consistent. Enjoy!
- mmorsi's blog
- Login to post comments
- Read more
Updated Rails 2.3.8 RPMS
Submitted by mmorsi on Tue, 2010-08-10 02:17
Happy to say that the Ruby 1.8.7 RPM has been community vetted, is in rawhide, and is scheduled to go into Fedora 14. Many thanks to all those on ruby-sig for their efforts.
Attached are some updated Rails 2.3.8 srpms which address most of the issues that I could find when updating. They entail the rebased upstream sources and handle any discrepancies between the versions. With any luck these should be pretty close to being good to go and are ready for testing and the eventual push into Fedora.
activesupport, activerecord, actionpack, actionmailer, activeresource, rails
Have at it!
- mmorsi's blog
- Login to post comments
- Read more
Rails 2.3.8 and 3.0.0.beta4 RPMS
Submitted by mmorsi on Fri, 2010-07-02 02:36
Before I get to rails, note that an updated Ruby 1.8.7 srpm is now available. The latest 1.8.7 release tarball is now being used (p299), there are many fixes and improvements, and its pretty close to the final version which will be pushed into Fedora (of course any and all feedback and additional improvements are more than welcome). Many thanks go out to Jim Meyering and Mamoru Tasaka for all their hard work and help to get to this point.
I'm also pleased to announce new Ruby on Rails rpms (built against Ruby 1.8.7) corresponding to the 2.3.8 and 3.0.0.beta4 Rails releases. Admittedly these will most likely require additional tweaking to resolve any issues as they are discovered, but what's there should be the complete Rails suite packaged and ready to deploy. Feedback for any / all of these packages would also be much appreciated.
Without further ado, here is the Rails 2.3.8 suite:
activesupport: srpm rpm
activerecord: srpm rpm
actionpack: srpm rpm
actionmailer: srpm rpm
activeresource: srpm rpm
rails: srpm rpm
And here is the the Rails 3.0.0.beta4 suite:
activesupport: srpm rpm
activerecord: srpm rpm
actionpack: srpm rpm
actionmailer: srpm rpm
activeresource: srpm rpm
rails: srpm rpm
Also note you will need an updated sqlite3-ruby rpm to build either set, which I provide here (rpm here).
Enjoy!
- mmorsi's blog
- Login to post comments
- Read more
Installing a RoR app on a webhost
Submitted by mmorsi on Tue, 2009-10-27 17:41Just figure I'd share a few steps which are useful in getting a RoR application up and running on a web hosting provider. Obviously the steps will vary depending on your specific provider, but most should be the same assuming your given access to a home directory on the web server under which public_html resides.
- Install your rails app in a location _not_ under ~/public_html. For example ~/rails/appname would be a good place
- Run through your application specific install instructions, configuring db if necessary
- Link the 'public' directory under the rails root, to the public_html directory, eg
ln -s ~/rails/appname/public ~/public_html/appname
- Edit .htaccess in the public directory, commenting out the following line and replacing it with:
# AddHandler fastcgi-script .fcgi AddHandler fcgid-script .fcgi(at least I had to do this w/ my provider, I'm not sure how many this applies to)
- Add your gem path to ~/rails/appname/config/environment.rb like so:
ENV['GEM_PATH']='/home/username/ruby/gems/gems:/usr/lib/ruby/gems/1.8/'
Obviously your local and system wide gem paths will vary depending on your system. Use the 'gem environment' command to determine what they are. - Finally you may also need to add the following to your ~/rails/appname/config/environment.rb:
config.action_controller.related_url_root = '/appname'
or if this doesn't work, add:
ActionController::AbstractRequest.related_url_root = '/appname'
This tells rails that our application is located under the '/appname' subdirectory of our webroot, eg in our case ~/public_html.
Though the process is pretty straightforward, since your not in control of the entire web server you may run into some tricky points as evident through the many related posts out there. Also your web application may have bugs of its own, further complicating the situation. Just stick to it and you should get it eventually.
- mmorsi's blog
- Login to post comments
- Read more
Shiny new site layout
Submitted by mmorsi on Tue, 2009-10-27 16:23So if you haven't noticed (eg if you're reading this via rss) I spent a while cleaning up and adding some useful features to this site. Unfortunately it took a little while to do so and involved some pain; you'd always hope that upgrading software and installing new plugins would be pretty simple and straightforward, but we all know how that goes.
I started this process looking for a good Ruby On Rails CMS webapp, as I'm far more familiar nowadays w/ Ruby and the Rails framework than I am w/ PHP. There are a few out there, including radiant and typo, but I don't feel like they currently meet my needs, and in addition I was having quite some trouble getting them up and running (especially Radiant; look out for a post in the very near future on installing Rails software on a webhost).
So I decided to stick w/ drupal for now. Changed the theme to a more configurable one. Indexed the site content & provided a search box (btw for those new to drupal, one can easily index your site content by navigating to http://sitelocation/cron.php, or setup a cron job to wget that url). Added a tag cloud (which required a hack that took a while to discover), code syntax highlighting support, and even a favicon (among other features).
I've also enabled anonymous comments again, having put in place various spam control measures.
As always if anything looks of or doesn't work, feel free to drop me an email and I'll look into it. And be sure to check back soon for new content!
[And for those drupal users who are still reading this far, a good tip to debug any module running on your system, without access to a debugger, is the use the 'watchdog' facility, that provides logger functionality. Results can be viewed in the Drupal admin reports interface which is populated from the Drupal db watchdog table].
- mmorsi's blog
- Login to post comments
- Read more
More ActiveRecord Funkiness
Submitted by mmorsi on Mon, 2009-10-12 21:46Another caveat to look out for when using activerecord, especially for those of you who are using the nested set module and have optimistic locking turned on (which I'm guessing by the timestamp on that patch is making its ways to the Linux repos just about now).
It turns out when you go to destroy a model object in a nested set, it first updates the lft and rgt attributes before running the correct delete query against the db. eg
UPDATE "pools" SET lft = CASE WHEN lft > 13 THEN (lft - 2) ELSE lft END, rgt = CASE WHEN rgt > 13 THEN (rgt - 2 ELSE rgt END WHERE (1 = 1)
....
DELETE FROM "pools" WHERE "id" = 8 AND "lock_version" = 0
....
Unfortunately when optimistic locking is enabled (as it seems to be by default now), activerecord will detect the record has already been updated before it attempts to destroy it and will throw a "StaleObjectError" reporting "Attempted to delete a stale object". The object being used to perform the update, no longer reflects the current db state (granted it's only "lock_version", the db field used to perform lock checks, that is inconsistent, but that is enough to throw it off).
The only work around which I know of right now, save fixing ActiveRecord itself, is to use delete instead of destroy, which obviously is not optimal and doesn't work for all cases. I need to look into this issue some more myself, and will follow up with a better fix if I find it. Until then this also may help
- mmorsi's blog
- Login to post comments
- Read more
Bit of weirdness with ActiveRecord
Submitted by mmorsi on Wed, 2009-09-30 20:26Figure I'd pass on a bit of weirdness concerning Ruby's ActiveRecord. Apparently when two models class are associated via rails the association takes place through a custom ActiveRecord association class, eg if a host model has many instances of the nic model, host.nics will be an instance of ActiveRecord::Associations::AssociationProxy and _not_ a mere array of nics. AssociationProxy acts very similarily to an array, providing the expected functionality to get/set associated classes.
All of this is as expected, the weirdness arising from the fact a call to host.nics.class would return the 'Array' class and not 'AssociationProxy'. This is because AssociationProxy hijacks many methods and uses them for its own purposes, including the 'class' method.
To access an array from an instance of AssociationProxy, merely call the 'all' method, eg
host.nics.all.find { |nic| some_test }
Trying to call the 'find' method on nics directly will result in an ActiveRecord error: "Couldn't find Nic without an ID" as the AssociationProxy find method is called instead of the one you want.
- mmorsi's blog
- Login to post comments
- Read more
Difference between delete and destroy in ActiveRecord
Submitted by mmorsi on Wed, 2009-08-26 16:57This is well documented, but I keep running into the same issue and never learn from my mistakes. ;-)
When you invoke 'destroy' or 'destroy_all' on an ActiveRecord object, the ActiveRecord 'destruction' process is initiated, it analyzes the class you're deleting, it determines what it should do for dependencies, runs through validations, etc.
When you invoke 'delete' or 'delete_all' on an object, ActiveRecord merely tries to run the 'DELETE FROM tablename WHERE conditions' query against the db, performing no other ActiveRecord-level tasks.
This also holds true for the :dependent option passed into the ActiveRecord::Association methods (belongs_to, has_one, has_many, has_and_belongs_to_many)
Thus if you have a circular dependency between two model classes, and you want to delete both related records when one is deleted, one of the :dependent clauses _must_ be :destroy and the other :delete. if both are set to :destroy you'll have an infinite loop resulting in a "SystemStackError: stack level too deep" exception.
For example
class Person < ActiveRecord::Base
has_one :address, :dependent => :destroy
validate_presence_of :address
end
class Address < ActiveRecord::Base
belongs_to :person, :dependent => :delete
validates_presence_of :person
end
With this scenario, you are free to add a foreign key constraint to the person_id field of the addresses table and everything will still behave as expected. Best of luck.
- mmorsi's blog
- Login to post comments
- Read more
Another word of warning about Ruby On Rails 2.3
Submitted by mmorsi on Thu, 2009-07-30 15:50I'm not sure if this was introduced in 2.3 or a prior version but today several of us working on the oVirt project discovered that Rails is now _requiring_ i18n localization translations for alot of stuff, namely the activerecord model validation errors.
Though i18n is a great feature, we have no time to write lots of translations right now, and we're still looking into how to turn this off (if even possible, I will update this post with the final solution when we find it).
IMHO the rails guys really shot themselves in the foot with this one. Even if it can be turned off, it shouldn't be turned on by default as its an extra feature than many people don't need and currently causes major breakage.
If you are a developer working on rails, make sure to look out for this when upgrading your rails instance (honestly I would wait, there seems to be many new 'features' causing issues and breakage).
</rant>
- mmorsi's blog
- Login to post comments
- Read more





