Best ruby-on-rails questions in April 2011

Rails 3 install error: "invalid value for @cert_chain"

17 votes

I'm trying to install Rails 3 on a new OS X Snow Leopard machine (with dev tools installed), and when I sudo gem install rails, I get the following error:

ERROR:  While executing gem ... (Gem::FormatException)
builder-2.1.2 has an invalid value for @cert_chain

And the update fails. Has anyone seen this before? I greped the builder-2.1.2 directory for 'cert_chain,' but couldn't find any clues.

Ruby version is 1.8.7

OS X 10.6.6

Thanks!

This is an issue with Rubygems version 1.7.1. Upgrading to 1.7.2 or above, or downgrading to 1.6.2, fixes this.

To upgrade (preferred):

gem update --system

To downgrade:

gem update --system 1.6.2

do..end vs curly braces for blocks in Ruby

13 votes

A have a coworker who is actively trying to convince me that I should not use do..end and instead use curly braces for defining multiline blocks in Ruby.

I'm firmly in the camp of only using curly braces for short one-liners and do..end for everything else. But I thought I would reach out to the greater community to get some resolution.

So which is it, and why? (Example of some shoulda code)

context do
  setup { do_some_setup() }
  should "do somthing" do
    # some more code...
  end
end

or

context {
  setup { do_some_setup() }
  should("do somthing") {
    # some more code...
  }
}

Personally, just looking at the above answers the question for me, but I wanted to open this up to the greater community.

The general convention is to use do..end for multi-line blocks and curly braces for single line blocks, but there is also a difference between the two that can be illustrated with this example:

puts [1,2,3].map{ |k| k+1 }
2
3
4
=> nil
puts [1,2,3].map do |k| k+1; end
#<Enumerator:0x0000010a06d140>
=> nil

This means that {} has a higher precedence than do..end, so keep that in mind when deciding what you want to use.

P.S: One more example to keep in mind while you develop your preferences.

The following code:

task :rake => pre_rake_task do
  something
end

really means:

task(:rake => pre_rake_task){ something }

And this code:

task :rake => pre_rake_task {
  something
}

really means:

task :rake => (pre_rake_task { something })

So to get the actual definition that you want, with curly braces, you must do:

task(:rake => pre_rake_task) {
  something
}

Maybe using braces for parameters is something you want to do anyways, but if you don't it's probably best to use do..end in these cases to avoid this confusion.

Rack::Test resulting in ActiveRecord::AssociationTypeMismatch

10 votes

I have a problem when running all of my specs.

    ActiveRecord::AssociationTypeMismatch:
       Affiliate(#2154746360) expected, got Affiliate(#2199508660)

It would appear that my models are being loaded twice.

I have isolated the problem to be introduced with Rack::Test's requirement to define an "app" method.

require 'rack/test'
include Rack::Test::Methods

# app method is needed for rack-test
def app
  Rails.application
end

If I comment out Rails.application my rack specs do not work, but all of my other specs work fine. The use of Rails.application in the "app" method introduces the error above.

If I run my specs individually, everything works. I am preloading my environment with Spork and I think that the models are loaded first by Spork and then they are redefined when Rails.application is called in my "app" method.

Any ideas on how I can resolve this problem? I am not sure if there is another way to set my Rails app in the "app" method.

I am no longer having this problem anymore. I updated my gems. Rails was updated from 3.0.5 to 3.0.7 and I would guess that may have been the gem update that fixed my problem. Either way with newer versions of gems, my problem is fixed.

What is the best place to find information on what's planned for Edge Rails?

10 votes

I've recently been doing a bit of work with Rails Engines, specifically looking into getting RefineryCMS and Spree working on the same install but information as to what is planned and has been developed on edge rails is scarse. So I'm wondering if there is somewhere I've missed where people outline the plans for Rails+1.

I've investigated:

  • The mailing list
  • Lighthouse
  • The Google (good information on what has been done, not what is planned)
  • The github history (commit messages aren't usually that helpful)

Your best bet at this stage is to read the CHANGELOG files from the individual parts of Rails and attempt to glean from that what you can:

Other than that, there's the GitHub commits which may offer more insight (hahaha, I'm funny, hey?) or the Lighthouse which is sometimes good for finding the reasonings behind changes.

I would expect when Rails 3.1 is released there would be a write-up much like the 3.0 Release Notes detailing the changes. As to who's responsible for that, nobody knows.

As for Refinery and Spree, both of these projects would need to separate their code out into separate modules rather than polluting the global namespace. Controllers such as say, PagesController, would need to become Refinery::PagesController. Views for this controller would need to be moved into app/views/refinery/pages and the model would be in app/models/refinery within the engine itself.

The reasoning for this is so that applications are able to pollute the "global" namespace themselves with their own classes without overriding the functionality of the engines. It also stops engines from stepping on each other's toes.

The problem with getting Refinery and Spree to both do this would be twofold. 1) if you've heard of the phrase "herding cats" it would be similar, except replace cats with rabid zombie lions. 2) You would break backwards compatibility with EVERY SINGLE APPLICATION that has used Spree or Refinery.

Difference between plugins and Ruby gems?

7 votes

What is the difference between plugins and gems? What are the different uses of each? Where and why would you use one over the other?

Gem

  • Gem is a packaged ruby application using the packaging system defined by RubyGems.
  • Rails itself is a Gem.

    Rails gem is installed in jruby-1.0\lib\ruby\gems\1.8\gems\rails-1.2.3 as:

    DIR bin
    DIR builtin
    68,465 CHANGELOG
    DIR configs
    DIR dispatches
    DIR doc
    DIR environments
    307 fresh_rakefile
    DIR helpers
    DIR html
    DIR lib
    1,072 MIT-LICENSE
    11,969 Rakefile
    8,001 README
    The lib directory contains all the gem source code.

  • We can install,upgrade and query the gem version.If one uses a tool like my GemInstaller, one can easily automate the installation and loading of RubyGems with a single simple config file.

  • Gem installed for Ruby interpreter can be used system-wide by that interpreter.
  • Gem may be published as a plugin.
  • Can also be vendored in vendor/gems.

Plugin

  • Plugin is an extension of Rails Framework.
  • Can not be upgraded by using a command. To upgrade one have to uninstall and then install upgraded version.
  • Has to be hooked into rails application. (has to have init.rb)
  • Have an install.rb file.
  • Plugin cannot be published as a Gem.
  • Can only be used application wide.

Goldspike plugin is installed in vendor\plugins\rails-integration directory of the application as:
7,089 build.xml
1,141 LICENSE.txt
DIR plugins
6,675 pom.xml
1,447 README
DIR samples
plugins/goldspike directory consists of
24 init.rb
25 install.rb
DIR lib
549 Rakefile
536 README
DIR tasks
DIR test
The lib directory contains all the plugin source code.

Gem vs Plugins

  • Rails had a way of loading plugins from the vendor/plugins/ directory. This will most likely deprecate as Rails has added support for bundling gems with the project in the vendor/gems/ directory. The gem versions of rspec are the ones that are intended for everyday use. One should go with those unless you are supporting a Rails application in the 1.2.x family or earlier.
  • It often becomes quicker to check-in and check-out of a repository using Gems as you are not including the library in your actual application. There are often lesser problems using Plugins related to incompatibility arising concerning software versions among the distributed team.
  • General rule of thumb is to make Rails-specific functionality a plugin while making more general Ruby libraries into gems.

Is it worth changing from java/spring/hibernate to rails for a program that is undergoing massive changes?

7 votes

I have a project whose core domain is dramatically changing. It's possible to use 50% of the core functionality from this site and just add the 50% new functionality, but I am starting to consider that maybe it might be faster to simply redo the product in Rails. Development speed is very important.

There are some things I really like about java - the performance and scalability are very good. I am not a crappy Java developer, so my apps tend to run very well - better than the Rails sites I've seen. I've always accepted the idea that people probably just throw a little more money at the problem when it comes to using Rails, which probably works itself out in the end because of the insane productivity benefits.

I am actually quite agile with Java. I know it will still take me longer to add a basic entity to the system, but I am quick at it and I don't mind it that much. At least it's easy and straight-forward to do.

What I do mind is:

  • having to start/stop the server just to fix a route, lazy load exception, controller is going to wrong view, etc.
  • putting up with the fact that unit/integration tests sometimes have different results than the production environment (because annotations on controllers can't be tested, or lazy-loading exceptions occur during asynchronous service calls, or things like that). Knowing if your Jackson is marshaling your data properly is another Tomcat-only thing because it's handled by Spring. There are lots of things that go wrong after you have tested all that you can, and this frankly annoys the crap out of me.
  • putting up with the occasional maven/classloader problem that doesn't rear its ugly head until you deploy into tomcat. It gives the false impression that everything is "a-okay" when you are in your IDE.
  • having to put more effort to do database migrations than the ruby people ever have to.
  • putting up with framework bugs in Spring that block (it's happened about 5 times on this project since 2009) or Hibernate. I also don't like upgrading Spring Security and having them constantly change the configuration, apis and tag libraries over and over again. This is annoying.
  • wasting so much time uploading 58 MB war files to the server! These take me 12 minutes to upload whenever I need to deploy changes. If I forgot to do 'mvn clean' before I upload, Spring might complain that 2 beans exist with the same name because I moved one to a new package... and then I have to re-upload the whole stupid war file again. Why isn't "clean" run by default whenever you do 'mvn package' for?!?! Sometimes these frameworks and tools use the stupidest default settings. This is just so common in the Java world.
  • Having to spend hour(s) to figure out where a framework wants to plug-in your own custom implementation for something. This is very annoying. You can spend 2 hours sifting through Google and crappy documentation trying to figure out how to override Spring Security's authentication mechanism for example... and then spend only 5 minutes writing the actual implementation. Of course, they wrote paragraphs upon paragraphs explaining the architecture and how awesome it is, but nobody cares. For something so common, why not just give example source code and be done with it?
  • Waiting 10-15 seconds for Spring to start up whenever you want to run your integration tests. This is a drag.

There are a few things I like about Java though. Role-based access is very easy to do with Spring Security. Authentication is never that big of a gain, but I like the implementation inside of Spring.

I also like Spring's form-backing objects and @ModelAttribute. These are huge wins when it comes to controllers, and I don't know if Rails can do these things. I honestly never liked passing request parameters around in every action - Spring MVC is actually a lot easier to use when it comes to this common bloat.

Being able to cache really massive structures in memory and have them stay in memory when you start the application is also highly desirable, especially for this application actually. I have an in-memory thesaurus and grammar checker that needs to get called hundreds of times per request, so in memory is pretty much the fastest option for me.

Even still, I think I could rebuild what I have in 2-3 weeks, and then add all of the new features in a few weeks using rails.

On the bright side, all of the really well-designed css, html and javascript could be ported over with very little problems.

I'd appreciate some advice on the subject before I continue.

PS: I could also go to Spring-ROO... but that would also be a considerable rework. I was never using JPA - I was using Hibernate directly. I am also not using JSP's - I am using Freemarker.

It takes more time to get good at Ruby, and Rails. I worked as an independent contractor as Spring and Hibernate expert myself, but I felt strangled by java and it's web frameworks so I decided to learn Ruby on Rails.

I would advice you to learn Ruby, from what I read you would probably master it, although get pretty frustrated with the very different way the use the ORM. I had issues with it, used to working on aggregate roots in Hibernate to the ActiveRecord one class one table kind of pattern. But hey, you could easily try out MongoDB to have some real fun.

Ruby is

  • less code
  • it's fast and scalable (slower than java on the specific tasks, but you get rid of stacks of layers.)
  • the problems are more often; which gem should I use. Luxorious!
  • a unique, big, sharing and caring open source community
  • nice frameworks, as Rails and Sinatra
  • powerful.
  • fun!

Would I advice you to do the project you describe in Ruby.

NO.

Not if speed of development matters. You will be slower, trust me. There's a lot to learn, it's conventions are not familiar to a java programmer and when you get stuck, lots of hours fly by.

The best option would be to hire a senior ruby developer to pair up with you and teach you. Be a good apprentice and you'll learn fast. Faster than me, I had to learn most by myself, which is really inefficient.

Good luck!

Need a memorable explanation of a proc and lambda

7 votes

I've tried reading about procs and lambda's but I have to keep re-reading the definition.

Can someone explain it to me in a way that is clear and memorable?

A few resources:

There's also an entire chapter in the Read Ruby 1.9 book.

HAML: remove white space after "link_to"

6 votes

The following code leaves a white space in HTML:

= link_to "Login", "#"

Normally, HAML allows to remove it by putting ">" at the end of the line, for example:

%input#query{:type => "text", :value => "Search"}>

However, that seems to be impossible, when Rails code is inserted.

How do I fix this?

How about this?

%span>= link_to "Login", "#"

It adds an extra span around the link, but those are pretty harmless.

I find haml can have a bit of a problem with some of these corner cases :(

How do you spawn an EventMachine "inside" a Rails app?

6 votes

I've got a Rails application, and am looking to add some sort of WebSocket support to it. From various googling, it appears that the best Ruby based WebSocket solution is em-websocket running on EventMachine.

I was wondering if there was a way to "integrate" an EventMachine reactor into Rails? Where do I put the initialization code? Is this the proper way to accomplish this?

I've seen this example that falls back on Sinatra to do an EventMachine GET request, but that isn't quite what I'm looking for.

Any help is appreciated.

I'd try using em-synchrony to start a reactor in a fiber. In a rails app you can probably start it in an initializer since it sounds like you just want to leave the reactor running to respond to websocket requests. As suggested by the other answers I think you want to either setup socket communication with your reactor or use one of the asynchronous clients to a data store which both your reactor and rails code can read from and write to to exchange data.

Some of my coworkers put together some examples of starting EM reactors on demand in ruby code to run their tests within EventMachine. I'd try using that as a possible example; raking and testing with eventmachine

What is the preferred way to implement settings in a Ruby on Rails 3 application?

5 votes

I'm building a Rails 3 application that will have user-specific settings (looks, functionality, etc) and I was seeking some simple advice on whats the preferred way of actually implementing settings.

Do you prefer to have a dedicated model for this stuff? Are hashes acceptable to store in a database field? Do you prefer cookies or sessions over the database? Is an STI object best?

Maybe list some pros or cons to each different method if you can.

Thanks.

Hi, i've same situation like you, user specific setting. In my apps i prefer creating a model to store user's configuration i've User model and User_configuration model, where the relationship is one-to-one.

class User < ActiveRecord::Base
  has_one :user_configuration
end

class UserConfiguration < ActiveRecord::Base
  belongs_to :user, :dependent => :destroy
end

Or if you prefer using Hash and store it to database is possible to mark your field as serialize

class User < ActiveRecord::Base
  serialize :preferences, Hash
end

you can see it at http://api.rubyonrails.org/classes/ActiveRecord/Base.html

pros: - so far i've doesn't have any problem, it easy to maintenance

cons: - request more table in database

May be it could help you thanks.

Setting the cache_store in an initializer

5 votes

I'm trying to use redis-store as my Rails 3 cache_store. I also have an initializer/app_config.rb which loads a yaml file for config settings. In my initializer/redis.rb I have:

MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis'] 

However, this doesn't appear to work. If I do:

Rails.cache

in my rails console I can clearly see it's using the

ActiveSupport.Cache.FileStore

as the cache store instead of redis-store. However, if I add the config in my application.rb file like this:

config.cache_store = :redis_store 

it works just fine, except the app config initializer is loaded after application.rb, so I don't have access to APP_CONFIG.

Has anyone experienced this? I can't seem to set a cache store in an initializer.

After some research, a probable explanation is that the initialize_cache initializer is run way before the rails/initializers are. So if it's not defined earlier in the execution chain then the cache store wont be set. You have to configure it earlier in the chain, like in application.rb or environments/production.rb

My solution was to move the APP_CONFIG loading before the app gets configured like this:

APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]

and then in the same file:

config.cache_store = :redis_store, APP_CONFIG['redis']

Another option was to put the cache_store in a before_configuration block, something like this:

config.before_configuration do
  APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]
  config.cache_store = :redis_store, APP_CONFIG['redis']
end