Named scopes, still needed ?
Wijnand Wiersma vr 25 jun 10
I am wondering what the use cases are for named scope in the Rails3 release.
Just creating a class method which returns an ActiveRelation object gives more clear code and allows for more customisations.
The most obvious use case are old rails 2.3 lambda scopes.
See this example:
named_scope :for, lambda {|author| {:conditions => ["customer_id IS NULL OR customer_id = ?", author.customer_id]} }
You can call this like
Post.for(author) # eg anything that responds to customer
This looks like a method call, so I was happy to be able to do this in Rails3:
def self.for(testmaker) where(:customer_id => testmaker.customer_id) end
Now it’s not just like calling a method, it actually is a method!
For me this feels far more natural and thanks to Arel magic it just works in the same way too.
You can still chain it as if it was an instance method:
Post.limit(10).for(author)
So if we had to use the hackish lambda scopes regularly (the real need is questionable off course) and now we are better served with a class method: wouldn’t it be far more natural to skip named scopes and just create intelligent class methods?
Rails2:
named_scope :published, :conditions => {:published => true}
Rails3:
scope :published, where(:published => true)
The Rails3 way I like it:
def self.published where(:published => true) end
So unless anybody can give me a compelling reason to use named scopes (lines of code arguments will be rejected) I will proceed on this path.
I think Rails apps should become more Ruby like instead, too much magic hurts my brains.
And remember, everytime you write a lambda scope, god kills an unicorn.
Gepost in hor | 2 reacties
Phusion Passenger 2.2.15 just released
Paul Engel do 24 jun 10
Although earlier this month the guys of Phusion teased us with performance improvement stats of Passenger 3, they have just blogged about their Phusion Passenger 2.2.15 release.
It contains the following:
- Apache: Fixed incorrect temp dir cleanup by passenger-status
- Apache: Fixed some upload handling problems
- Nginx: Fixed compilation issues with Nginx >= 0.7.66
- Nginx: Changed its default Nginx version from 0.7.65 to 0.7.67
- Bundler: Fixed some problems
For further details, please check out their blog post in which upgrade instructions to 2.2.15 are also provided.
Gepost in hor | 0 reacties
Smooth menu's for real browsers
Johan Vermeulen wo 23 jun 10
With the features which are introduced in de CSS3 standard, it is possible to create rounded border corners. This can be a real time saver when slicing a website.
In this example I created a simple menu with rounded corners and a background image for the on hover and active events.
Result in browsers which support HTML5/CSS3:

Result in older browsers:

The HTML:
<ul> <li class="first"><a href="weblog.html">Weblog</a></li> <li><a href="weenies.html">Weenies</a></li> <li><a href="jobs.html">Jobs</a></li> <li class="last"><a href="zandbak.html">Zandbak</a></li> </ul>
Tweaks:
If you like you can add webkit and mozilla specific CSS to create the same results in Firefox 3 or webkit 1 enabled browsers:
-moz-border-radius: 10px; -webkit-border-radius: 10px;
Gepost in hor | 0 reacties
Custom Subdomains in Rails 3
Stephan Kaag wo 23 jun 10
Rails 3 supports subdomains out of the box, which is great. But did you know that the constraints in the Router can actually match patterns too? This means instead of hardcoding each subdomain into your routes you can allow your customers to decide their own subdomains.
I created a ‘lib/sub_domain.rb’ with the following code:
class AdminSubdomain def self.matches?(request) subdomain = request.subdomain ['admin', 'backend', 'adminpanel'].include? subdomain end end
In my routes.rb file I can now wrap all routes I want under a custom subdomain
# config/routes.rb TestApp::Application.routes.draw do |map| constraints(AdminSubdomain) do get "admin/index" end root :to => "home#index" end
The admin panel is now reachable at all three subdomains.
Gepost in hor | 0 reacties
nifty rails 3.0 methods
Daniel Willemse di 22 jun 10
So with the Rails 3.0 beta release as of late, I decided to try and play around with a new rails app. I’m pretty new to Ruby and Rails, so trying a new version of Rails (where they also changed routing, one of the things I personally have most problems with) was pretty challenging for me.
For those that haven’t yet checked out the new and cool stuff that’s available with rails 3, here’s some new code versus the 2.x version.
I had a fresh app in rails 2.3.5, which I tried to rebuild in rails 3.0.
In the old app for instance, there was code like:
Invoice.find(:all, :conditions => ["number > ?", 5]) or Invoice.find(:all, :order => "number DESC")
While in the new and improved rails,
you can write it much easier like this:
Invoice.where("number > ?", 5) and Invoice.order("number DESC")
The cool part about this, is that you can chain these new methods like this:
Invoice.order("number DESC").where("number > ?" 5)
This technique also works for named scopes. With rails 3.0, you can easily make a named scope as follows:
scope :above_1, where("number > 1") scope :below_5, where("number < 5") scope :above_1_and_below_5, above_1.below_5
(notice how it’s no longer called named_scope!!)
These scopes don’t make any sense, but you get the picture.
There are more of these new methods and as I play more with rails 3.0 I’ll try and update
So besides making it easier for you to chain together find options, why would you use these above the find methods
in rails 2.x?
Well I found my answer in a railscast where it is explained that the find option has been revised.
http://railscasts.com/episodes/202-active-record-queries-in-rails-3
In the video, it is shown that for instance, Model.scope (Article.recent in the video) returns an active record relation instead of performing the query. And that the query is performed when you try and get the actual data.
I have not yet been able to reproduce the same queries as in the railscast so I’ve not figured out how it works.
When I do however, I’ll try and share my findings and post an update.
Daniel Willemse
(the code I use, which should show me an active record relation in the console)
class Invoice < ActiveRecord::Base scope :above_1, where("number > 1") scope :below_5, where("number < 5") scope :above_1_and_below_5, above_1.below_5 end
>> i = Invoice.above_2_and_below_5.all
returns:
=>#<Invoice id: 4, …. ….. ….. , updated_at: "2010-06-22 19:50:29">]
Where I expect it to return something along the lines of
#<ActiveRecord::NamedScope::Scope
Gepost in hor | 1 reactie
Using the question mark for string equations.
Roy van der Meij di 22 jun 10
In rails we have the method Rails.env.production? which simply checks if Rails.env equals “production”
I kinda liked that and I was curious how they did that.
It appears that DHH himself made a class StringInquirer which had a nifty method_missing method.
Let’s check it out! (you can find this file in gems/active_support#{version}/lib/active_support/string_inquirer.rb)
module ActiveSupport class StringInquirer < String def method_missing(method_name, *arguments) if method_name.to_s[-1,1] == "?" self == method_name.to_s[0..-2] else super end end end end
With this knowledge we can do something like this.
fancyness = ActiveSupport::StringInquirer.new("fancy") fancyness.fancy? => true fancyness.lame? => false
So what do we do when we want to make this core functionality for any stringg?
Simple! Monkey patch the class String!
class String def method_missing(method_name, *arguments) if method_name.to_s[-1,1] == "?" self == method_name.to_s[0..-2] else super end end end "fancy".fancy? => true a = "awesome" a.awesome? => true a.stupid? => false
I personally like it more to have core extensions in separate modules instead of hacking the String class directly. So here is the cleaned up version.
module CoreExtensions module StringExtensions def method_missing(method_name, *arguments) if method_name.to_s[-1,1] == "?" self == method_name.to_s[0..-2] else super end end end end String.send :include, CoreExtensions::StringExtensions "fancy".fancy? => true
So… is it fancy?
Gepost in hor | 0 reacties
Netzke
Jeroen Bulters ma 21 jun 10
While I didn’t have the time to check it out myself yet; a friend of mine recommended me to have a look at Netzke. Netzke is a gem designed for usage with Rails which will allow you to easily include ExtJS components into your app (i.e. views).
I’m personally not the biggest fan of these semi-native bindings, but basic usage looks quite simple (and promising). This one goes into the list for usage on a next weekend-side-project.
Gepost in hor | 0 reacties
Immutable Attributes in Ruby On Rails
Chiel Wester ma 21 jun 10
Sometimes you want to have some attributes on models that can be changed only on creation or only on certain conditions.
Of course there is attr_protected (to prevent mass assignment) and attr_readonly, but with these methods it’s difficult to create the conditions we actually want to apply.
For these situations you can install the immutable_attributes gem. Simple set the following in your model:
class Relation < ActiveRecord::Base attr_immutable :name end
The attribute will be readonly for all (in this case) relations.
When you want to apply the immutable function only on certain conditions, you can do the following:
class Relation < ActiveRecord::Base validates_immutable :name, :if => Proc.new{|relation| relation.is_active?} end
This function works like a validation, so you will get an validation error when you try to change the specified attribute.
Gepost in hor | 0 reacties
Smash Into Vim
Dax Huiberts ma 14 jun 10
Not so long ago PeepCode released a screencast titled ‘Smash Into Vim’. In this screencast created by Andrew Stewart (voiceover by Dan Benjamin) you will be introduced to the power of the Vim text editor. Vim was specifically build to help programmers edit text more efficiently. Because of it’s origins in the terminal it can be daunting at first, but with a little practice you will find it well worth the effort.
The things that are covered are:
- Install Vim for your platform
- Use Vim for simple editing via SSH
- Configure Vim with sensible defaults (basic and advanced configurations are included in the code download)
- Use operators and commands to manipulate text
- Work with files, windows and buffers
- Install plugins
While you might be very happy with TextMate or another editor of your choice. I believe it’s a good idea to at least try it out. It may very well become your most powerful tool in your Ruby toolbox. As usual, this screencast costs a mere $9!
PS: Part II is in post-production and will go further into advanced editing and plugins.
Gepost in hor | 1 reactie
Fixing i18n backend cache key when using memcached and Ruby 1.8.6
Paul Engel vr 11 jun 10
Implementing internationalization for Rails sites is a common thing. Most of you are likely using the i18n library developed by Sven Fuchs.
Backends and chaining them together
The default backend (I18n::Backend:: Simple) reads its translations from YAML files stored in the /config/locales directory and uses an in-memory hash to ensure efficiency. In most cases, this backend is sufficient enough when the application doesn’t require translation management by end-users. But if so, storing translations within YAML files isn’t preferred. You want to use a database for doing this.
Fortunately, i18n also provides a backend for database storage (I18n::Backend::ActiveRecord). Chaining both backends enables you to define translations within the YAML files and to override them with translations stored in the database.
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
The usage of memcached ensures efficiency.
require "memcache" yaml = YAML.load(File.read(File.join(RAILS_ROOT, "config", "memcached.yml"))) config = yaml["defaults"].merge yaml[RAILS_ENV || "development"] mem_cache = MemCache.new config mem_cache.servers = config["servers"] I18n.cache_store = ActiveSupport::Cache.lookup_store :mem_cache_store, mem_cache
The problem
Using this setup in Ruby 1.8.6 can raise an error caused by an invalid memcached cache key. This key is generated by the protected method I18n::Backend::Cache.cache_key which doesn’t provide a clean key in Ruby 1.8.6 as it uses the Hash.hash method to create the key. The pitfall is that isn’t reliable in Ruby < 1.8.7:
{}.hash != {}.hash.
The fix
A solution is to upgrade Ruby, but doing this can bring a lot of side effects to Ruby dependent libraries on your system. We are clearly searching for some 1.8.7 goodies to use in 1.8.6. Fortunately, Marc-André Lafortune has created the gem Backports which provides us just that.
But as backports is not endorsed by ruby-core and you’re noted to use this with caution!
To fix the I18n cache key problem, just extract the hash method backport and use it in your project:
class Hash def hash h = 0 each do |key, value| h ^= key.hash ^ value.hash end h end unless {}.hash == {}.hash end
Enjoy!
Gepost in hor | 0 reacties
Welkom op Holland On Rails
Het startpunt voor Ruby On Rails in Nederland. Vind de laatste technieken, meningen en nieuwtjes.Recente Jobs
Gezocht: Ruby On Rails ontwikkelaar (junior of senior)
Eet, drink en droom jij over Ruby On Rails? Wil jij het liefste dag en nacht bezig zijn met jehobby; super coole webapplicaties ontwikkelen in Ruby On Rails?
Dan willen wij jou graag een podium bieden om je Ruby skills te vertonen aan onze nationale en internationale klanten!
@ Internetbureau Holder, Obdam
Bekijk alle jobs »»
Gereedschapskist
Onmisbare tools vooriedere developer!
- Ruby On Rails
Framework voor de web 2.0 developer. Eindelijk vooruitgang! - TextMate
Editor for true pro's
Typ, tab, top :-)
Nee, niet voor Win. - Made On A Mac
En nou is het over met die saaie grijze Windows bak van je!
Auteurs op deze site
Chris Obdam
'Less is more' evangelist, past dit ook dagelijks toe op zijn tandenborstel.Chiel Wester
Snelheidswonder op Ruby wielen. Leuk om mee te pair-programmen ;-)