41Studio's Blog http://blog.41studio.com Most recent posts at 41Studio's Blog posterous.com Fri, 10 Feb 2012 00:13:35 -0800 The game just completely changed http://blog.41studio.com/the-game-just-completely-changed http://blog.41studio.com/the-game-just-completely-changed

Something insane is happening in the creative industry and all of you need to know about it. Two recent events have completely changed the career prospects for Web Designers and Developers: 1) Frank Chimero's Kickstarter project and 2) Natasha Wescoat's live painting sessions.

Let me explain ...

 

Frank’s Story …

Frank Chimero is a talented designer who thought “You know, it’d be awesome to write a book.”

Photo of Frank with a painting of a city behind him

Instead of going the traditional publishing route, he decided to ask for funding to write the book before he’d even started. He used a site called Kickstarter which allows people to ‘back’ projects by pledging money and if the goal is hit, then the money is paid out and the project begins. He announced the project with this tweet:

Announcing The Shape of Design, the book. Back me on Kickstarter? kickstarter.com/projects/30453…

He decided to set the goal at $27,000 and insanely, he crushed that goal in less than a day, and now, two days later he’s up to $51,000. I’m not sure how he came up with the $27K figure, but I assume he added up the costs for his time, the printing and shipping.

Let me share one more interesting project, before I share my conclusions …

Natasha’s Story …

Natasha Wescoat is a very talented painter.

One of Natasha's painting that's a tree with bright circles for leaves and an orange sky

Natasha paints live on uStream and Justin.tv. As she works on a piece, viewers watch and by the end, there is often a bidding.

Here she is starting the painting …

Ustream video of Natasha starting a painting.

and then finishing it about 3 hours later …

Ustream video of Natasha finishing a painting.

What’s the huge shift?

The power of crowd-funding sites like Kickstarter, and the entertainment draw of Ustream have created a brand new channel for designers (and developers, which I’ll cover in a minute) to get paid for doing something they love.

This model allows anyone with talent and a decent following (Twitter, Blog, Facebook, etc) to leave freelance and client work behind. They can simply move from  project to project, knowing that it will be a success before they even start, while also determining the subject matter of the work.

It’s similar to the patronage model, but you get to pick the creation. Wild.

Natasha has learned to combine her talent (painting) with live entertainment. There’s something very intriguing about watching someone live-paint, knowing you might be able to purchase the work at the end.

So how can you take part in this revolution?

  1. Put in a good 2-3 years of hard work, building your following on Twitter, Facebook and your blog. Frank has around 13,000 Twitter followers, which is a decent chunk, but isn’t impossible to attain. You can’t expect to just click your fingers and succeed like this. Gotta do the time.
  2. Be damn good at what you do. You’ll need to build a reputation and being kick ass and creative. Obviously no one is going to want to fund you if your work is sub-par.
  3. Have an idea that’s creative, original and valuable. Just because you’ve achieved #1 and #2 above doesn’t mean any project your throw up on Kickstarter will succeed. The project has to stand on its own two feet.

What about Developers?

I also believe there’s an exciting opportunity for Developers here as well. Imagine this scenario …

You spot a much needed tool or service. A new framework, iPhone app, plug-in, etc. You decide you can create an awesome solution and you can dedicate a couple months to building something awesome. You create the project on Kickstarter and everyone who funds you gets a copy of the app/software/etc and a few exclusive goodies.

I’m hugely excited by this new model and it’ll be interesting to see what other projects crop up.

I can’t help thinking that two folks who should’ve done this are Ethan Marcotte (a book on Responsive Design) and Elliot Jay Stocks (with 8faces). I know Ethan is publishing a RD book with A Book Apart soon, but he could’ve completely controlled the project on his own if he wished. Getting published by a respected source like Zeldman and Co is awesome but it would’ve been interesting to see him, Cederholm or Keith do their books via Kickstarter instead.

Love to hear your thoughts!

Source : http://thinkvitamin.com/design/the-game-just-completely-changed/

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 09 Feb 2012 22:09:30 -0800 5 Fabulous Friday Links for Web Developers http://blog.41studio.com/5-fabulous-friday-links-for-web-developers http://blog.41studio.com/5-fabulous-friday-links-for-web-developers

It’s Friday again. Where did the last 5 days go? Since many of you are starting a long weekend, you probably won’t appreciate a long, complex tutorial. Therefore, here are a number of useful links I’ve discovered recently which could ease your development burden when you return next week…

CopyPasteCharacter.com
copypastecharacter.com

If you don’t know your &raquo’s from your &rdquo’s, copypastecharacter.com is a great tool which could help you find the right HTML entity. Click any symbol and its character or HTML code is copied to the clipboard.

If you require something a little more sophisticated, the XHTML Character Entity Reference provides a categorized list of characters with their HTML entity code, numerical reference and unicode representation (useful for JavaScript).

ge.tt
Easy File Sharing with Ge.tt

Do your clients often try to send you videos or other large files from their AOL email account? Save their sanity and suggest they use Ge.tt.

While there are many file sharing systems, Ge.tt is one of the easiest I’ve seen. It’s free, there’s no need to register and there are no file size limits. File links can be sent to others via email, Twitter or Facebook. Your data is retained for 90 days, you can access download statistics and the developers are creating an API.

supportdetails.com
Support Details

It’s Friday, 5.30pm and your phone rings. It’s ClientX and they’re not happy. “My site doesn’t work.” they claim, “It’s broken and I want it fixed now”. You load the URL and everything seems fine.

A long conversation follows as you try to identify the problem. Unfortunately, the client doesn’t know what browser they’re using — they don’t know what a browser is. It’s futile to ask about their OS, screen resolution, color depth, version of Flash, or JavaScript state.

Fortunately, supportdetails.com can answer many questions for you. Ask them to visit the site and enter your email address to receive a report about their system. They’re probably running IE3.0 on their Great Aunt’s Windows 3.1 PC.

8bitalpha.com
Convert PNGs with 8bitalpha.com

24-bit alpha-transparent PNGs are great. However, Fireworks users know that 8-bit PNGs are smaller and work in more browsers. If you don’t use Fireworks, 8bitalpha.com may help. Simply drag your 24-bit masterpiece into the page and have an optimized 8-bit version returned.

ninite.com
Install and Update Software with ninite.com

Have you recently received a new PC? How long did it take to download and install your vital software, developer tools, browsers, media players, runtimes, virus checkers and utilities? How long does it take to find, download and install updates?

Save those lost hours with ninite.com. It’s easy: choose your applications, download the installer, and let it do the hard work for you. The installer can be run again when you want to check for updates.

ninite.com is primarily for Windows users who don’t have the luxury of a built-in package manager. That said, a Linux version of ninite.com is also available.

Bonus Link: URL Hunter

Are you fed up with fancy 3D games? URL Hunter is possibly the simplest browser-based game ever devised. It’s played in the URL bar and your task is to shoot the ‘a’ characters. It’s hardly Call of Duty, but it’ll give you a few moments pleasure and no one will realize you’re enjoying yourself.

Have a great weekend!

Source : http://www.sitepoint.com/5-fabulous-links-web-developers/

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Mon, 06 Feb 2012 20:40:00 -0800 8 Reasons I love Ruby http://blog.41studio.com/8-reasons-i-love-ruby http://blog.41studio.com/8-reasons-i-love-ruby

In the last year I abandoned .NET for Ruby in my side projects and actual job.  In the interest of not explaining my rationale over and over again, I'm going to talk here about why I love Ruby so passionately.

Ruby is vastly more productive than Java or .NET.

I had heard that Ruby was more productive for years. Each time I rolled my eyes, confident these developers lacked my Resharper/Automocking/Generics/Fluent API Magic.  Then l developed in Rails at GiveCamp last year and holy dear god I was nearly as productive in this framework I barely knew as I was in ASP.NET MVC, a platform I knew inside out.  What the hell was I doing with my life? 

I am not an outlier in feeling this way.  Never in the history of man has a software developer said "I'm stuck doing Ruby for my day job but I'm really hoping to find a job in .NET or Java."

Thoughtworks, a company I'm pretty sure only employs geniuses, conducted a survey on the productivity of their Ruby projects.  Out of 30 projects surveyed, 80% reported being at least 50% more productive because they used Ruby instead of Java or .NET with more than 60% claiming a productivity increase of 2x or greater. (Only one project (3.3% of projects) reported actually being slower for using Ruby, while 90% of projects reported some increase in productivity.)

In my own estimation, I'd say Rails is somewhere between two and three times more productive than ASP.NET (MVC or Webforms).  That means I believe a 5 month .NET project could be done in 2 months in Ruby!

Why is Ruby so many times more productive than .NET or Java?

1) Gems

There have been rumblings about .NET's need for a package management system, but that is not what makes the gem ecosystem.

What makes Ruby Gems awesome is that, for various reasons, there are gems for everything!  So many problems are already solved!

Video of me whenever I run "gem install"

 

Some recent requirements I solved with a simple "gem install":

  • PDFs. gem install pdfkit, add two lines of code and bam, I can add .pdf to a route and get a pdf version.
  • Excel.  just setup the mime type with one line of code, call .to_xls on any collection and I get an excel doc returned!
  • Verb conjugation.  I need to figure out how to get the past perfect test of a verb.  "gem install verbs"
  • Here's a hard one:  I'd need profile pictures uploaded to amazon s3 and cropped to three different thumbnail sizes.  I also need to run asynchronously so my user doesn't wait 30 seconds after updating their profile.  And I should show a default picture of the appropiate size if they haven't uploaded one.  This would take how many days in .NET?  In Ruby I just had to gem install delayed_paperclip and just call one method in my model.  I had this working in minutes. 

Then there's twitter, devise, pickle, formtastic, friendly_id... 

2) Consistency

Ruby tools evolve naturally. Survival of the fittest. The best tools rise to the top; bad tools get ignored. There are different ORMs, view engines, etc, but they usually only exist when they solve a different need.  Ruby tools are crafted to fulfill actual needs and don't have to compete with tools dreamed up to be marketable.  There is no split in the Ruby community where half the developers use MSRake or MSSinatra.  Every single developer knows and uses Rake!

Because everyone knows Rake, ActiveRecord, Cucumber and RSpec, being a Rails Dev actually means something.  I have to be very skeptical when interviewing a ".NET developer" and figure out what kind of .NET dev they are. 

Every .NET project reinvents the wheel with deployment, ORMs, Migrations, project structure, while every Rails project is nearly identical. This might sound boring, but these inconsequential decisions are already made and free you to solve the actual business problem.  (This consistency is also what allows so many gems to integrate so seamlessly)  It also lets me be confident any experienced Rails Dev is a good fit for my project.  In fact, I hired someone on oDesk this month to help out on a Rails side project. I looked at his github, saw he knew his stuff and he was able to dive in with no ramp up time at all.  I would never dream of doing that in .NET.  

3) Git/Github

With DVCS and the ubiquitness of github, if I need to add functionality to a project, I just can!  I just fork, reference my fork in my GemFile (this lets my repository build my version of the gem instead of the one at rubygems.org) and issue a pull request to the project's owner.  Hopefully my change gets pulled into the main repo and I can go back to referencing the main gem.  It's not the end of the world if that doesn't happen, thanks to the beauty of git, I can keep pulling in new changes from the main repo.  The fact that this project will actually have automated tests lets me be comfortable that my patch did not break any functionality.  

On that note...

4) Testing

Testing isn't controversial in the Ruby community.  Projects without tests are seldom taken seriously.  On Codeplex, it's difficult to find a .NET project with unit tests.

Unit testing in a static language is much harder.  For example, you can not use the ActiveRecord pattern, because you would have no way to mock your database operations.  You have to wrap every single service in an interface and inject every depdenency.  That means wraping things that seem outright silly, like having a class and interface just to wrap DateTime.Now so you can stub it for your tests.  In Ruby, you can mock anything at any time.  (And for the usecase I just mentioned it's of course solved, simply gem install timecop.)

5) Ruby, The Language

Much is made of this, so I won't dwell here.  However the power, the beauty, expressiveness and openness of the language is what allows this community to thrive in the first place, so it definitely shouldn't be overlooked. 

6) Things just work

The Ruby community hates configuration and complexity.  When I install a gem, it usually Just Works.  

Ruby developers seek to ease the pain .NET developers don't even think about.  Ruby has made great progress in removing the pain of XML, CSS, JavaScript Includes, running unit testsmanaging dependencies, automating deployment and even JavaScript testing, 

7) Heroku

This fits in the Things that Just Work bullet, but no place on this planet can you set up a website in 30 seconds with three lines of code.  Then once you're set up, you can just click a checkbox to get email notifications of exceptions, or code analysis, or a MongoDB database or a bulk email service.  And deployment is just "git deploy heroku."  Oh yeah, and its all free until you start doing signficiant traffic.  I never dreamed of hosting so many websites so painlessly. 

8) Simplicity 

Have I mentioned that all these problems are solved and all this shit just works all the time?

I realized how far I had strayed from .NET when a .NET friend told me "Yeah, I got Azure set up in two hours."

I replied, "Ouch, I'm sorry."

"What? I thought that was pretty good."

Source : http://iggy.nu/8-reasons-i-love-ruby

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Sun, 05 Feb 2012 23:18:05 -0800 10 Must Have Ruby Gems http://blog.41studio.com/10-must-have-ruby-gems http://blog.41studio.com/10-must-have-ruby-gems

One of the most beautiful things about Ruby development is the ease of adding functionality through packaged libraries called gems. With the power of Bundler, you can quickly add and manage gems in few lines of code. I'd like to share the 10 must-have gems which allow me to focus on what's unique to my app.

 

1. Devise (Authentication)

Just about every public-facing Rails app needs some type of authentication scheme. Authentication is often confused and interchanged with authorization, although the 2 terms have very distinct meanings.

In a nut shell, authentication determines if users are who they say they are, commonly through a username and password combination. Authorization determines which actions an authenticated user can perform. Devise is a solution to the former problem. I recently switched from AuthLogic in favor of Devise’s advanced engine for providing models, controllers and views. AuthLogic leaves it up to the developer to create the views and controllers. However, views are generally the first thing you should override, but thankfully Devise makes that easy as well.

Devise is a very active gem, and in conjunction with omniauth, has made it incredibly simple to setup Facebook and Twitter login buttons in less than a dozen lines of code. At first, the engine seemed too overbearing for me, but once I understood how easy it is to override and extend Devise, I made the switch.

https://github.com/plataformatec/devise

2. CanCan (Authorization)

CanCan is an incredibly easy way to define and access user permissions. All apps tend to have some sort of authorization scheme, but it’s generally setup adhoc, and leads to very messy view code. If you have dozens of if object.user == current_user statements littered among your views and controllers, it’s time to take a look at CanCan.

If you aren’t authorizing the current user to modify a provided object in update actions, a user could send a post request to update another user’s project, for example. With CanCan, your app’s authorization scheme is defined centrally in an Ability model. By using the can? method, you can check to see if the current user is authorized to perform an action to handle conditional view rendering.

CanCan also makes it dead simple to authorize controller actions and handle authorization exceptions.

https://github.com/ryanb/cancan

3. Haml (Better Views)

HAML transforms your views with sexy, minimalist syntax that makes Ruby jealous. HAML’s indent based syntax eliminates end tags, and provides a more concise way of defining HTML and interpreting embedded ruby code.

I made the switch about 2 years ago and cringe every time I have to work with “real” HTML. Even mediocre HTML ninjas will be comfortable with HAML in a few days. HAML takes:

1
2
<h2><%= @user.name %></h2>
<div class="about">About Me: <%= @user.about %></div>

and makes it great:

1
2
h2= @user.name
.about About Me: #{@user.about}

http://haml-lang.com/

4. Compass (Better CSS)

Compass is a framework that does to CSS what HAML does to HTML. In conjunction with SASS, a CSS replacement, Compass provides native frameworks such as Blueprint. By leveraging SASS mixins, you can finally ditch non-semantic classes such as “div-8″ for blueprint columns.

The other major benefit of SASS is variables, most commonly used for color definitions. Tear up that sticky note with hex colors and start using color variables. Better yet, create an entire color palette using SASS’s lighten and darken functions.

http://compass-style.org/

5. Will Paginate (Pagination)

Will Paginate is by far the reigning champ when it comes to pagination. Originally ported from PHP, will_paginate can get you up and running with pagination in a few lines of code. There are practically no contenders, and rightfully so since I can’t think of too many ways to make this better. OK, Ajax pagination would be really awesome.

https://github.com/mislav/will_paginate/wiki

6. Paperclip (File Attachments)

If you’ve ever written code to handle file uploads and image processing, you surely cringe every time a client says “I’d like the user to have his or her own photo”–that is until you’ve worked with a gem as easy to use as this one.

Paperclip makes it trivial to restrict content types, define storage locations and access a model’s associated attachment. If you’re working with images, you can define styles with corresponding resolutions for use-cases such as thumbnails and profile sizes.

Even if you are using Heroku with its read-only file system, paperclip works beautifully with outside storage mechanism such as Amazon S3.

https://github.com/thoughtbot/paperclip

7. Meta Where (ActiveRecord Query Extensions)

This is a less popular gem that I ran into when I got sick of passing in complex SQL strings into ARel where methods, and then finding the inconsistencies between MySQL (development) SQLite (test) and Postgres (Heroku).

The default behavior of chaining ARel where methods is to “and” the conditions. Meta_where lets you define complex boolean logic on conditions, even among sub tables.

http://metautonomo.us/projects/metawhere/

8. DelayedJob (Background Job Scheduling)

One of the easiest ways to speed up some Rails apps is to push more complex processing into background jobs. The most notorious offenders are image processing and emailing.

Instead of having the user wait on the browser while an email sends or an image is processed, (both items that can wait) offload these tasks to a later time and let the user continue.

This gem automatically handles scheduling and provides an easy way to run all scheduled jobs. With Heroku, running the jobs is as easy as pushing up the workers a notch.

https://github.com/tobi/delayed_job

9. Has Scope (Collection Filtering)

This gem does to filtering what will_paginate did to pagination. Most rails apps dealing with item collections that need to be filtered by an attribute such as location, category or tag, will benefit from this. By leveraging existing model scopes, you can keep your controllers lean without conditional statements for each possible filter query.

Simply use the has_scope method with the scope name in the controller, and pass the model into apply_scopes to take advantage instant filtering.

https://github.com/plataformatec/has_scope

10. Rack SSL Enforcer (HTTPS Redirection)

With all the hype a few months ago over Firesheep, even basic, non credit-card accepting, apps that use passwords need for SSL. Sure, there’s no requirement that you secure your app, and even if a user’s account was compromised it may cause little harm.

However, most people reuse the same password for everything, and I wouldn’t like to have on my conscience that a user’s online banking password was stolen because they accessed my app without SSL at Starbucks.

Rack SSL Enforcer is a dead simple gem that uses Rack to redirect non https requests to the https equivalent. The default configuration forces HTTPS on every request, but can easily be overridden to only required it on some URL and URL patterns.

You may be familiar with the ssl_requirement gem originally released by DHH. This isn’t compatible with Rails 3, although there is a fork bartt-ssl_requirement that is which I’ve used in previous projects. I never really liked the idea of HTTPS redirection happening after the request gets to the controller. The rack solution is much simpler, especially for securing an entire app.

https://github.com/tobmatth/rack-ssl-enforcer

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Sun, 05 Feb 2012 22:45:19 -0800 Caching Techniques in Ruby on Rails http://blog.41studio.com/caching-techniques-in-ruby-on-rails http://blog.41studio.com/caching-techniques-in-ruby-on-rails

1. Basic Caching

This is an introduction to the three types of caching techniques that Rails provides by default without the use of any third party plugins.

To get started make sure config.action_controller.perform_caching is set to true for your environment. This flag is normally set in the corresponding config/environments/*.rb. By default, caching is disabled for development and test, and enabled for production.

config.action_controller.perform_caching = true

  1.1 Page Caching

Page caching is a Rails mechanism which allows the request for a generated page to be fulfilled by the webserver, without ever having to go through the Rails stack at all. Obviously, this is super-fast. Unfortunately, it can’t be applied to every situation (such as pages that need authentication) and since the webserver is literally just serving a file from the filesystem, cache expiration is an issue that needs to be dealt with.

So, how do you enable this super-fast cache behavior? Suppose you have a controller called ProductsController and an index action that lists all the products. You could enable caching for this action like this:

class ProductsController <

ActionController caches_page :index def index; end end

The first time anyone requests products/index, Rails will generate a file called index.html. If a web server see this file, it will be served in response to the next request for products/index, without your Rails application being called.

By default, the page cache directory is set to Rails.public_path (which is usually set to File.join(self.root, "public") – that is, the public directory under your Rails application’s root). This can be configured by changing the configuration setting config.action_controller.page_cache_directory. Changing the default from /public helps avoid naming conflicts, since you may want to put other static html in /public, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from.

The page caching mechanism will automatically add a .html extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages. This can be configured by changing the configuration setting config.action_controller.page_cache_extension.

In order to expire this page when a new product is added you could extend the products controller like this:

class ProductsController <

ActionController caches_page :index def index; end def create expire_page

:action => :index end end

If you want a more complicated expiration scheme, you can use cache sweepers to expire cached objects when things change. This is covered in the section on Sweepers.

Note: Page caching ignores all parameters, so /products/list?page=1 will be written out to the filesystem as /products/list.html and if someone requests /products/list?page=2, they will be returned the same result as page=1. Be careful when page caching GET parameters in the URL!

  1.2 Action Caching

One of the issues with page caching is that you cannot use it for pages that require checking code to determine whether the user should be permitted access. This is where Action Caching comes in. action caching works like page caching except for the fact that the incoming web request does go from the web server to the Rails stack and Action Pack so that before filters can be run on it before the cache is served. This allows you to use authentication and other restrictions while still serving the result of the output from a cached copy.

Clearing the cache works in the exact same way as with page caching.

Let’s say you only wanted authenticated users to edit or create a Product object, but still cache those pages:

class ProductsController <

ActionController before_filter :authenticate,:only => [ :edit, :create ]

caches_page :index caches_action :edit def index; end def create expire_page

:action => :index expire_action :action => :edit end def edit; end end

You can also use :if (or :unless) to pass a Proc that specifies when the action should be cached. Also, you can use :layout => false to cache without layout so that dynamic information in the layout such as the name of the logged-in user or the number of items in the cart can be left uncached. This feature is available as of Rails 2.2.

You can modify the default action cache path by passing a :cache_path option. This will be passed directly to ActionCachePath.path_for. This is handy for actions with multiple possible routes that should be cached differently. If a block is given, it is called with the current controller instance.

Finally, if you are using memcached, you can also pass :expires_in. In fact, all parameters not used by caches_action are sent to the underlying cache store.

  1.3 Fragment Caching

Life would be perfect if we could get away with caching the entire contents of a page or action and serving it out to the world. Unfortunately, dynamic web applications usually build pages with a variety of components not all of which have the same caching characteristics. In order to address such a dynamically created page where different parts of the page need to be cached and expired differently Rails provides a mechanism called Fragment Caching.

Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in.

As an example, if you wanted to show all the orders placed on your website in real time and didn’t want to cache that part of the page, but did want to cache the part of the page which lists all products available, you could use this piece of code:

<% Order.find_recent.each do |o|

%> <%= o.buyer.name %> bought <% o.product.name %> <% end

%> <% cache do %> All available products: <% Product.find(:all).each

do |p| %> <%= link_to p.name, product_url(p) %> <% end %> <%

end %>

The cache block in our example will bind to the action that called it and is written out to the same place as the action cache, which means that if you want to cache multiple fragments per action, you should provide an action_suffix to the cache call:

<% cache(:action => 'recent',

:action_suffix => 'all_prods') do %> All available products:

You can expire the cache using the expire_fragment method, like so:

expire_fragment(:controller =>

'products', :action => 'recent', :action_suffix => 'all_prods)

If you don’t want the cache block to bind to the action that called it, you can also use globally keyed fragments. To do this, call the cache method with a key, like so:

<% cache(:key =>

['all_available_products', @latest_product.created_at].join(':')) do %> All

available products: <% end %>

This fragment is then available to all actions in the ProductsController using the key and can be expired the same way:

expire_fragment(:key =>

['all_available_products', @latest_product.created_at].join(':'))

  1.4 Sweepers

Cache sweeping is a mechanism which allows you to get around having a ton of expire_{page,action,fragment} calls in your code. It does this by moving all the work required to expire cached content into na ActionController::Caching::Sweeper class. This class is an Observer that looks for changes to an object via callbacks, and when a change occurs it expires the caches associated with that object in an around or after filter.

Continuing with our Product controller example, we could rewrite it with a sweeper like this:

class StoreSweeper <

ActionController::Caching::Sweeper # This sweeper is going to keep an eye on the

Product model observe Product # If our sweeper detects that a Product was

created call this def after_create(product) expire_cache_for(product) end # If

our sweeper detects that a Product was updated call this def

after_update(product) expire_cache_for(product) end # If our sweeper detects

that a Product was deleted call this def after_destroy(product)

expire_cache_for(product) end private def expire_cache_for(record) # Expire the

list page now that we added a new product expire_page(:controller =>

'#{record}', :action => 'list') # Expire a fragment

expire_fragment(:controller => '#{record}', :action => 'recent',

:action_suffix => 'all_products') end end

The sweeper has to be added to the controller that will use it. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following:

class ProductsController <

ActionController before_filter :authenticate,:only => [ :edit, :create ]

caches_page :list caches_action :edit cache_sweeper :store_sweeper,:only =>

[ :create ] def list; end def create expire_page :action => :list

expire_action :action => :edit end def edit; end end

  1.5 SQL Caching

Query caching is a Rails feature that caches the result set returned by each query. If Rails encounters the same query again during the current request, it will used the cached result set as opposed to running the query against the database.

For example:

class ProductsController <

ActionController before_filter :authenticate,:only => [ :edit, :create ]

caches_page :list caches_action :edit cache_sweeper :store_sweeper,:only =>

[ :create ] def list # Run a find query Product.find(:all) ... # Run the same

query again Product.find(:all) end def create expire_page :action => :list

expire_action :action => :edit end def edit; end end

In the ‘list’ action above, the result set returned by the first Product.find(:all) will be cached and will be used to avoid querying the database again the second time that finder is called.

Query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action.

  1.6 Cache Stores

Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk.

Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to cache strings. Some cache store implementations, like MemoryStore, are able to cache arbitrary Ruby objects, but don’t count on every cache store to be able to do that.

The default cache stores provided with Rails include:

1) ActiveSupport::Cache::MemoryStore: A cache store implementation which stores everything into memory in the same process. If you’re running multiple Ruby on Rails server processes (which is the case if you’re using mongrel_cluster or Phusion Passenger), then this means that your Rails server process instances won’t be able to share cache data with each other. If your application never performs manual cache item expiry (e.g. when you‘re using generational cache keys), then using MemoryStore is ok. Otherwise, consider carefully whether you should be using this cache store.

MemoryStoreis not only able to store strings, but also arbitrary Ruby objects. MemoryStoreis not thread-safe. Use SynchronizedMemoryStore instead if you

need thread-safety.

ActionController::Base.cache_store =

:memory_store

2) ActiveSupport::Cache::FileStore: Cached data is stored on the disk. This is the default store and the default path for this store is: /tmp/cache. Works well for all types of environments and allows all processes running from the same application directory to access the cached content. If /tmp/cache does not exist, the default store becomes MemoryStore.

ActionController::Base.cache_store =

:file_store, "/path/to/cache/directory"

3) ActiveSupport::Cache::DRbStore: Cached data is stored in a separate shared DRb process that all servers communicate with. This works for all environments and only keeps one cache around for all processes, but requires that you run and manage a separate DRb process.

ActionController::Base.cache_store =

:drb_store, "druby://localhost:9192"

4) MemCached store: Works like DRbStore, but uses Danga’s MemCache instead. Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites.

Special features:

  • Clustering and load balancing. One can specify multiple memcached servers, and MemCacheStore will load balance between all available servers. If a server goes down, then MemCacheStore will ignore it until it goes back online.
  • Time-based expiry support. See write and the :expires_in option.
  • Per-request in memory cache for all communication with the MemCache server(s).

It also accepts a hash of additional options:

  • :namespace- specifies a string that will automatically be prepended to keys when accessing the memcached store.
  • :readonly- a boolean value that when set to true will make the store read-only, with an error raised on any attempt to write.
  • :multithread – a boolean value that adds thread safety to read/write operations – it is unlikely you’ll need to use this option as the Rails threadsafe! method offers the same functionality.

The read and write methods of the MemCacheStore accept an options hash too. When reading you can specify :raw => true to prevent the object being marshaled (by default this is false which means the raw value in the cache is passed to Marshal.load before being returned to you.)

When writing to the cache it is also possible to specify :raw => true. This means that the value is not passed to Marshal.dump before being stored in the cache (by default this is false).

The write method also accepts an :unless_exist flag which determines whether the memcached add (when true) or set (when false) method is used to store the item in the cache and an :expires_in option that specifies the time-to-live for the cached item in seconds.

ActionController::Base.cache_store =

:mem_cache_store, "localhost"

5) ActiveSupport::Cache::SynchronizedMemoryStore: Like ActiveSupport::Cache::MemoryStore but thread-safe.

ActionController::Base.cache_store =

:synchronized_memory_store

6) ActiveSupport::Cache::CompressedMemCacheStore: Works just like the regular MemCacheStore but uses GZip to decompress/compress on read/write.

ActionController::Base.cache_store =

:compressed_mem_cache_store, "localhost"

7) Custom store: You can define your own cache store (new in Rails 2.1)

ActionController::Base.cache_store =

MyOwnStore.new("parameter")

config.cache_store can be used in place of

ActionController::Base.cache_storein the Rails::Initializer.run block in

environment.rb.

In addition to all of this, Rails also adds the ActiveRecord::Base#cache_key method that generates a key using the class name, id and updated_at timestamp (if available).

An example:

Rails.cache.read("city") # => nil

Rails.cache.write("city", "Duckburgh") Rails.cache.read("city") # =>

"Duckburgh"

2. Conditional GET Support

Conditional GETs are a feature of the HTTP specification that provide a way for web servers to tell browsers that the response to a GET request hasn’t changed since the last request and can be safely pulled from the browser cache.

They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers to pass back and forth both a unique content identifier and the timestamp of when the content was last changed. If the browser makes a request where the content identifier (etag) or last modified since timestamp matches the server’s version then the server only needs to send back an empty response with a not modified status.

It is the server’s (i.e. our) responsibility to look for a last modified timestamp and the if-none-match header and determine whether or not to send back the full response. With conditional-get support in rails this is a pretty easy task:

class ProductsController <

ApplicationController def show @product = Product.find(params[:id]) # If the

request is stale according to the given timestamp and etag value # (i.e. it

needs to be processed again) then execute this block if stale?(:last_modified

=> @product.updated_at.utc, :etag => @product) respond_to do |wants| # ...

normal response processing end end # If the request is fresh (i.e. it's not

modified) then you don't need to do # anything. The default render checks for

this using the parameters # used in the previous call to stale? and will

automatically send a # :not_modified. So that's it, you're done. end

If you don’t have any special response processing and are using the default rendering mechanism (i.e. you’re not using respond_to or calling render yourself) then you’ve got an easy helper in fresh_when:

class ProductsController <

ApplicationController # This will automatically send back a :not_modified if the

request is fresh, # and will render the default template (product.*) if it's

stale. def show @product = Product.find(params[:id]) fresh_when :last_modified

=> @product.published_at.utc, :etag => @article end end

Source : http://blog.adroit-inc.com/web/caching-techniques-in-ruby-on-rails-3/167/

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 02 Feb 2012 23:43:23 -0800 Are You the Best Ruby on Rails Developer You Know? http://blog.41studio.com/are-you-the-best-ruby-on-rails-developer-you http://blog.41studio.com/are-you-the-best-ruby-on-rails-developer-you

Photo by Naval History & Heritage Command.

Over the last few years, we have placed developers with a fairly wide range of skill sets.  Some are more junior developers with a year or two of experience.  Others are top-level guys/gals who have authored Rails books that are probably sitting on your bookshelf. 

If you are one of the top Rails developers at your company or in your circle of Rails pals, this post is for you. 

Having amazing Rails skills yourself is great and will make you a valuable asset at any company you choose to join.  But there is something that will make you infinitely more valuable: the ability to mentor other Rails developers.  If you are a good mentor, you have the ability to raise the level of work on your entire team, providing much greater value to your team, company, and the product or service you are building as a whole.  

It’s kind of like the Chinese proverb: “Give a man a fish; you have fed him for a day. Teach a man to fish; you have fed him for a lifetime.”  The ability to teach others fuels unprecedented growth and potential for your team.
 
If you have great Rails skills yourself, you are good to go.  But what will take you to that next level?  The ability to mentor those around you.  As an individual, even the best Rails developer has his/her limit in terms of the number of lines of code one can write and the number of bugs one can fix in a given time period.  But imagine if you could clone yourself (or the best developer at your company) through mentorship.  How much stronger would your team be?  How much better would your product be?

Source : http://mirrorplacement.com/blog/are-you-the-best-ruby-on-rails-developer-you-...

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 02 Feb 2012 22:52:35 -0800 5 Signs You're Ready For a New Rails Job http://blog.41studio.com/5-signs-youre-ready-for-a-new-rails-job http://blog.41studio.com/5-signs-youre-ready-for-a-new-rails-job

Photo by Alex93vf.

 

It’s easy to get stuck in a job that’s no longer the right fit for you. Maybe it was exciting at first, but that was years ago and the company has changed. Or maybe you have changed. Either way, one of the biggest challenges in realizing it’s time for a new job is the simple but strong force of inertia. It’s much easier to stay put than it is to freshen up your resume, go on interviews, and ask for the job. So, to help you battle the power of inertia, here are some signs that you’re ready for your next Rails job:

  1. You’d much rather work on your own side projects than your 9-5 work. If your own side projects are consistently more engaging and fulfilling than your day job, it may be time for a new 9-5. Sure, side projects keep things interesting, but at the end of the day, they are still on the side. It makes no sense to spend all day, every day coding a project you’ve lost interest in. You wouldn’t work on a side project if it wasn’t fun. Why spend your most productive hours working on something you no longer enjoy?
  2. The dev team doesn’t get along or seems generally unhappy. If your coworkers are unhappy, it may be a sign that the development environment at your current place of work isn’t the best. Sometimes it’s easier to recognize discontent in others than it is in ourselves. A less-than-ideal development environment may be due to the company’s culture or it may be due to the individuals on the team (usually it’s some of both). Whichever it is, this is a tell-tale sign that you’re ready to engage with a new group of people.
  3. You rarely feel challenged. You might believe in the product or service you’re helping to build, but if your current role is underwhelming, it’s time for something new. This may be as easy as talking to your manager about new projects you can take on. Maybe there’s a particularly challenging area of the codebase you want to tackle but haven’t been given the chance to yet. Maybe you want to try your hand at some front-end dev work. Asking for a new challenge at your current job can fulfill this need, but sometimes we all need a fresh, new problem to gnaw on. The good news: there are lots of new, challenging problems out there waiting for problem-solvers just like you.
  4. You have a sneaking suspicion that you’re underpaid. You were chatting with some friends at this week’s Meetup about salaries and were pretty shocked to hear some details of their compensation packages. It’s not all about the money, but it doesn’t make sense to stay in a job where your skills are undervalued. Today’s market is paying top dollar for Rails developers with your skills. If your current company can’t get up to speed with market rate, you can be sure that other companies will.
  5. You see yourself doing the same thing 5 years from now. In an ideal job, you feel fulfilled, challenged, and in a constant state of growth and change. If you think about your future work and imagine yourself doing the exact same things you are now, you’re staring at a big red flag. Careers are meant to evolve and progress with different projects and challenges. You can find new ways to grow and learn at the same company, but oftentimes to move forward in your career, you need to seek an entirely new set of challenges provided by a new company.

Do any of these signs describe your current job situation? Don’t give into the power of inertia. At the end of your career, do you want to look back and say “well that was comfortable and easy”? Probably not. Once you’ve realized that you are indeed ready to explore other options, polish that resume and give us a shout!

Source : http://mirrorplacement.com/blog/5-signs-youre-ready-for-a-new-rails-job

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Tue, 31 Jan 2012 23:15:53 -0800 Create Beautiful Administration Interfaces with Active Admin http://blog.41studio.com/create-beautiful-administration-interfaces-wi http://blog.41studio.com/create-beautiful-administration-interfaces-wi

Every web developer knows that creating an administration interface for their projects is an incredibly tedious task. Luckily, there are tools that make this task considerably simpler. In this tutorial, I’ll show you how to use Active Admin, a recently launched administration framework for Ruby on Rails applications.

 

You can use Active Admin to add an administration interface to your current project, or you can even use it to create a complete web application from scratch – quickly and easily.

Today, we’ll be doing the latter, by creating a fairly simple project management system. It might sound like quite a bit of work, but Active Admin will do the bulk of the work for us!


Step 1 – Set up the Development Environment

I’m going to assume you have some previous Ruby on Rails knowledge, especially involving model validations, since the rest of the application interface is going to be taken care of by Active Admin. Apart from that, you should have a development environment for Ruby on Rails 3.1 already set up, including Ruby 1.9.2.

Refer to this article if you require assistance installing Ruby and Rails.

Create the application we’ll be working on, by running the following command in your Terminal:

rails new active_admin

Next, open your Gemfile and add the following lines:

gem 'activeadmin'
gem 'meta_search', '>= 1.1.0.pre'

The last gem is required for Active Admin to work with Rails 3.1, so don’t forget it. After that’s done, run thebundle install command to install the gems. Now, we need to finish installing Active Admin, by running the following command:

rails generate active_admin:install

This will generate all needed initializers and migrations for Active Admin to work. It will also create anAdminUser model for authentication, so run rake db:migrate to create all the needed database tables. Apart from that, you need to add one line to your config/environments/development.rb file, so sending emails works:

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

Once that’s done, run rails server and point your browser to localhost:3000/admin. You’ll be greeted with a nice login form. Just type “admin@example.com” as the email and “password” as the password, and hit “Login”. You should now see a nice administration interface.


Step 2 – Configuring our User Model

As you can see from the webpage you just generated, there’s not much you can do, yet. We’re going to need a way to edit our users, and we can do that using Active Admin. The framework uses what it calls “Resources”. Resources map models to administration panels. You need to generate them using a command in your terminal, so Active Admin can know their existence, so go ahead and run:

rails generate active_admin:resource AdminUser

The syntax for that command is simple: just write the database model’s name at the end. This will generate a file inside the app/admin folder, called admin_users.rb. Now, if you refresh your browser you’ll see a new link at the top bar, called “Admin Users”. Clicking that will take you to the Admin User administration panel. Now, it’ll probably look a little too cluttered, since by default, Active Admin shows all of the model’s columns, and considering that the framework uses Devise for authentication, you’ll see a bunch of columns that are not really necessary. This takes us to the first part of our customization: the index page.

Admin User

Customizing Active Admin resources is fairly easy (and fun if you ask me). Openapp/admin/admin_users.rb on your favorite text editor and make it look like this:

ActiveAdmin.register AdminUser do
  index do
    column :email
    column :current_sign_in_at
    column :last_sign_in_at
    column :sign_in_count
    default_actions
  end
end

Let’s review the code:

  • The first line is created by Active Admin, and, like it says, it registers a new resource. This created the menu link at the top bar and all of the default actions, like the table you just saw.
  • The index method allows us to customize the index view, which is the table that shows all rows.
  • Inside of the block you pass to the index method, you specify which columns you do want to appear on the table, ie. writing column :email will have Active Admin show that column on the view.
  • default_actions is a convenience method that creates one last column with links to the detail, edition and deletion of the row.

One final step for this view is to customize the form. If you click the “New Admin User” link on the top right, you’ll see that the form also contains all of the columns on the model, which is obviously not very useful. Since Active Admin uses Devise, we only need to enter an email address to create a user, and the rest should be taken care of by the authentication gem. To customize the forms that Active Admin displays, there’s a method, called (you guessed it) form:

ActiveAdmin.register AdminUser do
  index do
    # ...
  end

  form do |f|
    f.inputs "Admin Details" do
      f.input :email
    end
    f.buttons
  end
end

If the code looks familiar to you, you’ve probably used the Formtastic gem before. Let’s take a look at the code:

  • You specify the form’s view by calling the form method and passing it a block with an argument (f in this case).
  • f.inputs creates a fieldset. Word of advice: you have to add at least one fieldset. Fields outside of one will simply not appear on the view.
  • To create a field, you simply call f.input and pass a symbol with the name of the model’s column, in this case, “email”.
  • f.buttons creates the “Submit” and “Cancel” buttons.

You can further customize the forms using the DSL (Domain Specific Language) provided by Formtastic, so take a look at tutorials about this gem.

One last step for this form to work: since we’re not providing a password, Devise is not going to let us create the record, so we need to add some code to the AdminUser model:

after_create { |admin| admin.send_reset_password_instructions }

def password_required?
  new_record? ? false : super
end

The after_create callback makes sure Devise sends the user a link to create a new password, and thepassword_required? method will allow us to create a user without providing a password.

Go try it out. Create a user, and then check your email for a link, which should let you create a new password, and log you into the sytem.


Step 3 – Projects

We are going to create a simple Project Management system. Not anything too complicated though, just something that will let us manage projects and tasks for the project, and assign tasks to certain users. First thing, is to create a project model:

rails generate model Project title:string

Active Admin relies on Rails’ models for validation, and we don’t want projects with no title, so let’s add some validations to the generated model:

# rails
validates :title, :presence => true

Now, we need to generate an Active Admin resource, by running:

rails generate active_admin:resource Project

For now, that’s all we need for projects. After migrating your database, take a look at the interface that you just created. Creating a project with no title fails, which is what we expected. See how much you accomplished with just a few lines of code?


Step 4 – Tasks

Projects aren’t very useful without tasks right? Let’s add that:

rails generate model Task project_id:integer admin_user_id:integer title:string is_done:boolean due_date:date

This creates a task model that we can associate with projects and users. The idea is that a task is assigned to someone and belongs to a project. We need to set those relations and validations in the model:

class Task < ActiveRecord::Base
  belongs_to :project
  belongs_to :admin_user

  validates :title, :project_id, :admin_user_id, :presence => true
  validates :is_done, :inclusion => { :in => [true, false] }
end

Remember to add the relations to the Project and AdminUser models as well:

class AdminUser < ActiveRecord::Base
  has_many :tasks

  # ...
end
class Project < ActiveRecord::Base
  has_many :tasks

  # ...
end

Migrate the database, and register the task model with Active Admin:

rails generate active_admin:resource Task

Now go and take a look at the tasks panel in your browser. You just created a project management system! Good job.

 

Step 5 – Making It Even Better

The system we just created isn’t too sophisticated. Luckily, Active Admin is not just about creating a nice scaffolding system, it gives you far more power than that. Let’s start with the Projects section. We don’t really need the idcreated and updated columns there, and we certainly don’t need to be able to search using those columns. Let’s make that happen:

index do
  column :title do |project|
    link_to project.title, admin_project_path(project)
  end

  default_actions
end

# Filter only by title
filter :title

A few notes here:

  • When you specify columns, you can customize what is printed on every row. Simply pass a block with an argument to it, and return whatever you want in there. In this case, we are printing a link to the project’s detail page, which is easier than clicking the “View” link on the right.
  • The filters on the right are also customizable. Just add a call to filter for every column you want to be able to filter with.

The project’s detail page is a little boring don’t you think? We don’t need the date columns and the id here, and we could show a list of the tasks more directly. Customizing the detail page is accomplished by using the show method in the app/admin/projects.rb file:

show :title => :title do
  panel "Tasks" do
    table_for project.tasks do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
end

Let’s walk through the code:

  • show :title => :title specifies the title the page will have. The second :title specifies the model’s column that will be used.
  • By calling panel "Tasks" we create a panel with the given title. Within it, we create a custom table for the project’s tasks, using table_for.
  • We then specify each column and the content’s it should have for each row.
    • The “Status” column will contain “Done” or “Pending” whether the task is done or not.status_tag is a method that renders the word passed with a very nice style, and you can define the color by passing a second argument with either : ok:warning and :error for the colors green, orange and red respectively.
    • The “Title” column will contain a link to the task so we can edit it.
    • The “Assigned To” column just contains the email of the person responsible.
    • The “Due Date” will contain the date the task is due, or just a “-” if there’s no date set.

Step 6 – Some Tweaks for the Tasks

How about an easy way to filter tasks that are due this week? Or tasks that are late? That’s easy! Just use a scope. In the tasks.rb file, add this:

scope :all, :default => true
scope :due_this_week do |tasks|
  tasks.where('due_date > ? and due_date < ?', Time.now, 1.week.from_now)
end
scope :late do |tasks|
  tasks.where('due_date < ?', Time.now)
end
scope :mine do |tasks|
  tasks.where(:admin_user_id => current_admin_user.id)
end

Let’s review that code:

  • scope :all defines the default scope, showing all rows.
  • scope accepts a symbol for the name, and you can pass a block with an argument. Inside the block you can refine a search according to what you need. You can also define the scope inside the model and simply name it the same as in this file.
  • As you can see, you can access the current logged in user’s object using current_admin_user.
Tasks2

Check it out! Just above the table, you’ll see some links, which quickly show you how many tasks there are per scope, and lets you quickly filter the list. You should further customize the table and search filters, but I’ll leave that task to you.

We’re now going to tweak the task’s detail view a bit, since it looks rather cluttered:

show do
  panel "Task Details" do
    attributes_table_for task do
      row("Status") { status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      row("Title") { task.title }
      row("Project") { link_to task.project.title, admin_project_path(task.project) }
      row("Assigned To") { link_to task.admin_user.email, admin_admin_user_path(task.admin_user) }
      row("Due Date") { task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end

  active_admin_comments
end

This will show a table for the attributes of the model (hence the method’s name, attributes_table_for). You specify the model, in this case task, and in the block passed, you define the rows you want to show. It’s roughly the same we defined for the project’s detail page, only for the task. You may be asking yourself: What’s that “active_admin_comments” method call for? Well, Active Admin provides a simple commenting system for each model. I enabled it here because commenting on a task could be very useful to discuss functionality, or something similar. If you don’t call that method, comments will be hidden.

Tasks

There’s another thing I’d like to show when viewing a task’s detail, and that’s the rest of the assignee’s tasks for that project. That’s easily done using sidebars!

sidebar "Other Tasks For This User", :only => :show do
  table_for current_admin_user.tasks.where(:project_id => task.project) do |t|
    t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
    t.column("Title") { |task| link_to task.title, admin_task_path(task) }
  end
end

This creates a sidebar panel, titled “Other Tasks For This User”, which is shown only on the “show” page. It will show a table for the currentadminuser, and all tasks where the project is the same as the project being shown (you see, task here will refer to the task being shown, since it’s a detail page for one task). The rest is more or less the same as before: some columns with task details.


Step 7 – The Dashboard

You may have noticed, when you first launched your browser and logged into your app, that there was a “Dashboard” section. This is a fully customizable page where you can show nearly anything: tables, statistics, whatever. We’re just going to add the user’s task list as an example. Open up the dashboards.rbfile and revise it, like so:

ActiveAdmin::Dashboards.build do
  section "Your tasks for this week" do
    table_for current_admin_user.tasks.where('due_date > ? and due_date < ?', Time.now, 1.week.from_now) do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end

  section "Tasks that are late" do
    table_for current_admin_user.tasks.where('due_date < ?', Time.now) do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
end

The code should be fairly familiar to you. It essentially creates two sections (using the section method and a title), with one table each, which displays current and late tasks, respectively.

Dashboard

Conclusion

We’ve created an extensive application in very few steps. You may be surprised to know that there are plenty more features that Active Admin has to offer, but it’s not possible to cover them all in just one tutorial, certainly. If you’re interested in learning more about this gem, visit activeadmin.info.

You also might like to check out my project, called active_invoices on GitHub, which is a complete invoicing application made entirely with Active Admin.

Source : http://net.tutsplus.com/tutorials/ruby/create-beautiful-administration-interfaces-with-active-admin/

 

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Tue, 31 Jan 2012 22:51:13 -0800 Humorously informative Rails logging http://blog.41studio.com/humorously-informative-rails-logging http://blog.41studio.com/humorously-informative-rails-logging

I’ll just leave this here:

 

01 module ActiveSupport
02   # Format the buffered logger with timestamp/severity info.
03   class BufferedLogger
04     NUMBER_TO_NAME_MAP  = {0=>'meh'1=>'fyi'2=>'hmm'3=>'wtf'4=>'omg'5=>'???'}
05     NUMBER_TO_COLOR_MAP = {0=>'1;30',  1=>'0;36'2=>'0;33'3=>'1;33',  4=>'1;31',  5=>'0;37'}
06  
07     def add(severity, message = nil, progname = nil, &block)
08       return if @level > severity
09       sevstring = NUMBER_TO_NAME_MAP[severity]
10       color     = NUMBER_TO_COLOR_MAP[severity]
11  
12       message = (message || (block && block.call) || progname).to_s
13       message = "\033[0;37m#{Time.now.to_s(:db)}\033[0m [\033[#{color}m" + sprintf("%-3s","#{sevstring}") + "\033[0m] #{message.strip} (pid:#{$$})\n" unless message[-1] == ?\n
14       buffer << message
15       auto_flush
16       message
17     end
18   end
19 end

(To use, put this code in an initializer in config/initializers and restart. Provides highly-readable, timestamped, colorized logging for your rails app.)

Source : http://cbpowell.wordpress.com/2011/12/08/humorously-informative-rails-logging/

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Tue, 31 Jan 2012 00:15:59 -0800 Get Ruby on Rails working on Ubuntu 11.10 http://blog.41studio.com/get-ruby-on-rails-working-on-ubuntu-1110 http://blog.41studio.com/get-ruby-on-rails-working-on-ubuntu-1110

A long time I have not been using Ruby On Rails. I have decided to give it a try again, so started by installing on Ubuntu 11.10 in VirtualBox. From what I remember – I have never happened before having issue with RoR working out of the box. Unfortunately this was not the case this time. Everything started with something really new to me:

Invalid gemspec in [/var/lib/gems/1.8/specifications/json-1.6.1.gemspec]: invalid date format in specification: "2011-09-18 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/tilt-1.3.3.gemspec]: invalid date format in specification: "2011-08-25 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/json-1.6.1.gemspec]: invalid date format in specification: "2011-09-18 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/tilt-1.3.3.gemspec]: invalid date format in specification: "2011-08-25 00:00:00.000000000Z"

At the beginning I have tried to solve it in several ways – by installing ruby from APT sources via

 

1 sudo apt-get install rails

or just by installing rails from gems:

 

1 sudo gem install rails

Both re-installation and methods did not worked.
So I have to dig deeper.
After a lot of searching in google I found a simple solution. Obviously gemspecs have some different date formats that don’t validate. So if you have such a message, just run the following command:

 

1 sudo sed -i 's/ 00:00:00.000000000Z//' /var/lib/gems/1.8/specifications/*

This will fix the message. As soon as you install some new gem and you have this message – just run the script again.

Next it came the problem with SQLIte3:

Building native extensions. This could take a while...
ERROR: Error installing sqlite3-ruby:
ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'port install sqlite3 +universal'
or 'yum install sqlite3-devel' and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

This is solved by installing the development package of SQLite Ruby:

 

1 sudo apt-get install libsqlite3-dev

And at the end it came the problem with missing ExecJS engine:


/var/lib/gems/1.8/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
from /var/lib/gems/1.8/gems/execjs-1.2.9/lib/execjs.rb:5
from /home/npenkov/Projects/MyMeetingMinutes/config/application.rb:5:in `require'
from /home/npenkov/Projects/MyMeetingMinutes/config/application.rb:5
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:52:in `require'
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:52
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:49:in `tap'
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:49
from script/rails:6:in `require'
from script/rails:6

This I solved by downloading JavaScript engine from the URL mentioned (in my case Google V8) and putting on require in config/boot.rb

 

1 sudo gem install execjs
2 sudo gem install therubyracer

And adjust your applicaiton’s config/boot.rb:

 

1 require 'rubygems'
2 require 'execjs'
3 require 'v8'
4  
5 # Set up gems listed in the Gemfile.
6 ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
7  
8 require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

After all these fixes, everything ran smooth.
I am sure there could be more elegant way to fix all these issues, so feel free to propose solutions.
Enjoy!

Source : http://npenkov.com/2011/11/08/get-ruby-on-rails-working-on-ubuntu-11-10/

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Mon, 30 Jan 2012 23:09:12 -0800 ActiveModel: Make Any Ruby Object Feel Like ActiveRecord http://blog.41studio.com/activemodel-make-any-ruby-object-feel-like-ac http://blog.41studio.com/activemodel-make-any-ruby-object-feel-like-ac

Rails 2.3 has a ton of really nice functionality locked up in monolithic components. I’ve posted quite a bit about how we’ve opened up a lot of that functionality in ActionPack, making it easier to reuse the router, dispatcher, and individual parts of ActionController. ActiveModel is another way we’ve exposed useful functionality to you in Rails 3.

Before I Begin, The ActiveModel API

Before I begin, there are two major elements to ActiveModel. The first is the ActiveModel API, the interface that models must adhere to in order to gain compatibility with ActionPack’s helpers. I’ll be talking more about that soon, but for now, the important thing about the ActiveModel API is that your models can become ActiveModel compliant without using a single line of Rails code.

In order to help you ensure that your models are compliant, ActiveModel comes with a module called ActiveModel::Lint that you can include into your test cases to test compliance with the API:

class LintTest < ActiveModel::TestCase
  include ActiveModel::Lint::Tests
 
  class CompliantModel
    extend ActiveModel::Naming
 
    def to_model
      self
    end
 
    def valid?()      true end
    def new_record?() true end
    def destroyed?()  true end
 
    def errors
      obj = Object.new
      def obj.[](key)         [] end
      def obj.full_messages() [] end
      obj
    end
  end
 
  def setup
    @model = CompliantModel.new
  end
end

The ActiveModel::Lint::Tests provide a series of tests that are run against the @model, testing for compliance.

ActiveModel Modules

The second interesting part of ActiveModel is a series of modules provided by ActiveModel that you can use to implement common model functionality on your own Ruby objects. These modules were extracted from ActiveRecord, and are now included in ActiveRecord.

Because we’re dogfooding these modules, you can be assured that APIs you bring in to your models will remain consistent with ActiveRecord, and that they’ll continue to be maintained in future releases of Rails.

The ActiveModel comes with internationalization baked in, providing an avenue for much better community sharing around translating error messages and the like.

The Validations System

This was perhaps the most frustrating coupling in ActiveRecord, because it meant that people writing libraries for, say, CouchDB had to choose between painstakingly copying the API over, allowing inconsistencies to creep in, or just inventing a whole new API.

Validations have a few different elements.

First, declaring the validations themselves. You’ve seen the usage before in ActiveRecord:

class Person < ActiveRecord::Base
  validates_presence_of :first_name, :last_name
end

To do the same thing for a plain old Ruby object, simply do the following:

class Person
  include ActiveModel::Validations
 
  validates_presence_of :first_name, :last_name
 
  attr_accessor :first_name, :last_name
  def initialize(first_name, last_name)
    @first_name, @last_name = first_name, last_name
  end
end

The validations system calls read_attribute_for_validation to get the attribute, but by default, it aliases that method to send, which supports the standard Ruby attribute system ofattr_accessor.

To use a more custom attribute lookup, you can do:

class Person
  include ActiveModel::Validations
 
  validates_presence_of :first_name, :last_name
 
  def initialize(attributes = {})
    @attributes = attributes
  end
 
  def read_attribute_for_validation(key)
    @attributes[key]
  end
end

Let’s look at what a validator actually is. First of all, the validates_presence_of method:

def validates_presence_of(*attr_names)
  validates_with PresenceValidator, _merge_attributes(attr_names)
end

You can see that validates_presence_of is using the more primitive validates_with, passing it the validator class, merging in {:attributes => attribute_names} into the options passed to the validator. Next, the validator itself:

class PresenceValidator < EachValidator
  def validate(record)
    record.errors.add_on_blank(attributes, options[:message])
  end
end

The EachValidator that it inherits from validates each attribute with the validate method. In this case, it adds the error message to the record, only if the attribute is blank.

The add_on_blank method does add(attribute, :blank, :default => custom_message) if value.blank? (among other things), which is adding the localized:blank message to the object. If you take a look at the built-in locale/en.yml looks like:

en:
  errors:
    # The default format use in full error messages.
    format: "{{attribute}} {{message}}"
 
    # The values :model, :attribute and :value are always available for interpolation
    # The value :count is available when applicable. Can be used for pluralization.
    messages:
      inclusion: "is not included in the list"
      exclusion: "is reserved"
      invalid: "is invalid"
      confirmation: "doesn't match confirmation"
      accepted: "must be accepted"
      empty: "can't be empty"
      blank: "can't be blank"
      too_long: "is too long (maximum is {{count}} characters)"
      too_short: "is too short (minimum is {{count}} characters)"
      wrong_length: "is the wrong length (should be {{count}} characters)"
      not_a_number: "is not a number"
      greater_than: "must be greater than {{count}}"
      greater_than_or_equal_to: "must be greater than or equal to {{count}}"
      equal_to: "must be equal to {{count}}"
      less_than: "must be less than {{count}}"
      less_than_or_equal_to: "must be less than or equal to {{count}}"
      odd: "must be odd"
      even: "must be even"

As a result, the error message will read first_name can't be blank.

The Error object is also a part of ActiveModel.

Serialization

ActiveRecord also comes with default serialization for JSON and XML, allowing you to do things like: @person.to_json(:except => :comment).

The main important part of the serialization support is adding general support for specifying the attributes to include across all serializers. That means that you can do@person.to_xml(:except => :comment) as well.

To add serialization support to your own model, you will need to include the serialization module and implement attributes. Check it out:

class Person
  include ActiveModel::Serialization
 
  attr_accessor :attributes
  def initialize(attributes)
    @attributes = attributes
  end
end
 
p = Person.new(:first_name => "Yukihiro", :last_name => "Matsumoto")
p.to_json #=> %|{"first_name": "Yukihiro", "last_name": "Matsumoto"}|
p.to_json(:only => :first_name) #=> %|{"first_name": "Yukihiro"}|

You can also pass in a :methods option to specify methods to call for certain attributes that are determined dynamically.

Here's the Person model with validations and serialization:

class Person
  include ActiveModel::Validations
  include ActiveModel::Serialization
 
  validates_presence_of :first_name, :last_name
 
  attr_accessor :attributes
  def initialize(attributes = {})
    @attributes = attributes
  end
 
  def read_attribute_for_validation(key)
    @attributes[key]
  end
end

Others

Those are just two of the modules available in ActiveModel. Some others include:

  • AttributeMethods: Makes it easy to add attributes that are set like table_name :foo
  • Callbacks: ActiveRecord-style lifecycle callbacks.
  • Dirty: Support for dirty tracking
  • Naming: Default implementations of model.model_name, which are used by ActionPack (for instance, when you do render :partial => model
  • Observing: ActiveRecord-style observers
  • StateMachine: A simple state-machine implementation for models
  • Translation: The core translation support

This mostly reflects the first step of ActiveRecord extractions done by Josh Peek for his Google Summer of Code project last summer. Over time, I expect to see more extractions from ActiveRecord and more abstractions built up around ActiveModel.

I also expect to see a community building up around things like adding new validators, translations, serializers and more, especially now that they can be reused not only in ActiveRecord, but in MongoMapper, Cassandra Object, and other ORMs that leverage ActiveModel's built-in modules.

Source : http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Mon, 30 Jan 2012 20:05:55 -0800 What’s so special about Ruby on Rails? http://blog.41studio.com/whats-so-special-about-ruby-on-rails http://blog.41studio.com/whats-so-special-about-ruby-on-rails

There are many reasons why Rails is special, but in order to keep things fairly short (and n00b friendly) I won’t delve too deeply into the mechanics. Instead I’ll cover the things that first drew me to the framework… and subsequently got me hooked!

The best technologies

One of the biggest draws to Rails is that it saves you a heap of trouble having to spend weeks or months researching/agonising over which technologies to adopt or methodologies to follow. If you’ve ever wanted someone to just tell you what the best are, then consider yourself told!

Here’s a list of some of them:

 

  • MVC – Model View Controller architecture
  • Convention over Configuration – design paradigm; spend less time configuring things!
  • DRY – Don’t Repeat Yourself
  • TDD – Test Driven Development
  • jQuery – Javascript library
  • SASS – Better CSS (variables &∓ conditionals!)
  • CoffeeScript – Nicer/easier to read/write Javascript
  • REST – REpresentational State Transfer – architecture for (stateless) networked applications

Ok, so it’s all opinion – but does it really matter so long as they are some of (if not the) best? If they’re good enough for a large number of talented devs then they’re good enough for me! I’m more than happy to bow to their superior knowledge (and if you’re smart, so should you).

It’s widely accepted that most of the default technologies, and the way Rails is set-up or goes about things is nothing short of awesomeness (it’s not called the best web framework for nothing you know!) and where you might feel the defaults are not to your taste, it’s easy to swap and change. Want to use jQuery? Fine. Want to use Prototype? That’s cool too. Prefer RSpec? No problem!

Ruby

Another big draw is the underlying language. Ruby is beautiful, powerful, elegant – and doesn’t get in your way. In fact, it’s not uncommon for people to say Ruby devs are happy devs, and they really are! The syntax is clear, constructs make sense and it all just flows naturally, making it a lovely language to work with. But make no mistake, the simple exterior harbours a very powerful interior. One that allows Ruby programmers to do things that programmers of many other languages can only dream of. Such as metaprogramming.

Another common saying is that while many come to Ruby because of Rails, they stay because of Ruby – and I couldn’t agree more. Rails wouldn’t be possible in another language, you’d get something similar, but it wouldn’t be the same – you’d be left feeling something wasn’t quite right, or that it’s almost there. Ruby is a key reason why Rails is so awe-inspiring and why so much of what it does is possible. Ruby is an all-purpose language too, so it’s not just for web apps (like say PHP).

Its creator Yukihiro “Matz” Matsumoto, has said that he is “trying to make Ruby natural, not simple” in a way that mirrors life. And many would argue he’s done just that – and then some.

Ruby is a language that inspires you, excites you – but don’t take my word for it, take it for a spin and see for yourself why it’s so hawt!

The community

The Ruby community rocks. You get the feeling everyone is on the same wavelength, most Rails devs seem to use OS X and TextMate for example (even down to the same ‘theme’!) but the conventions run a lot deeper. Whether it’s indentation style or using parentheses in your method definitions or calls (they’re optional in Ruby) there’s a ‘Ruby way’ and most in the community stick to it. It’s not because Ruby users are mindless zombies mind you, it’s because we genuinely like the same things and have similarly high standards.

The most important thing however, is how passionate and helpful the community is. Good enough just isn’t good enough. That’s why test driven development (TDD) is such a big thing in the Ruby community, and why you can rest assured that your peers will always help you remain on top of your game.

As you might expect, with something so cherished at its heart the community are eager to help each other get the best out of it. Testament to this are all the resources that are not only free, but have clearly taken a lot of time and effort to put together. Here’s a quick list:tryruby.org – where you get to try (and learn) Ruby in your browser, the extremely enjoyableRails for Zombies where the Envy Labs team take you through some gory screencasts then test your knowledge via the brain browser, the fantastic Railscasts which is nearly as old as Rails itself (!) and Rails Tutorial which is an excellent step-by-step that helps you build a twitter clone. There’s also the IRC #rubyonrails channel (irc.freenode.net) where there’s always some cheery soul willing to lend a helping hand, and the utterly brilliant Ruby Mendicant University (and Ruby Best Practises from the same person, Gregory Brown). Finally I just have to include Rails Hotline where if you get stuck and fancy talking to someone who might be able to help, you can – for free!

Pretty awesome don’t you think? And did I mention they are all free!?

If all of that isn’t enough for you (it should be, but if it isn’t…) then there’s one last thing that I find quite remarkable. I’m fairly new to Ruby, yet many leading or well known figures in the community have taken time out to speak to me. Yehuda Katz talked to me at length about learning Rails. Gregg Pollack was happy to discuss my ideas of where Rails for Zombies could lead. Ryan Bigg made the effort to get a .mobi version of his book (Rails 3 in Action) to me as he was keen on hearing my thoughts, and even DHH (the creator of Rails) has discussed totally unrelated topics via Twitter. And that’s just the people who I know are leading figures! I’ve also exchanged tweets with a number of others but won’t include them here for brevity – well apart from Russ Olsen, the author of two of my favourite Ruby books (Design Patterns in Ruby and Eloquent Ruby) who is following me on Twitter. *Faints

It’s fantastic that a large number of people high up in the community are willing to take time out for the nubes. Is there any wonder why the community is as cool as it is?

What Rails can do for you

This is probably what most of you are wondering – so what can Rails do that an off-the-shelf app (like say a forum platform such as vBulletin) can’t? Pretty much everything!

Tired of being restricted to a forum or blog as the core of your community site? Want to create something completely different with control over the finest detail? Then you’ve out-grown such software and a custom solution is what you really need.

If you want to build a custom site, free from the constraints of a predefined app, then using a framework like Rails is your best option. You could just skip the framework, and code everything from scratch – but why bother when so much of the hard work has already been done for you? Most of the fiddly ‘boring’ stuff is all set ready to go – you can just concentrate on the exciting stuff! And more importantly, if you’re not an expert already, Rails will teach you best practises that might otherwise take a lifetime to learn.

Additionally, and something that will interest you as you progress as a Rubyist, is that Rails allows you to use many of its components for your own non-Rails apps. Such as Active Record (the Object Relational Mapper) Active Support (Rails libraries) and even Action View (view helpers). Some of these even extend core Ruby classes such as Array, String and Hash – which is impossible in most other languages!

What will I need to learn?

Thankfully Rails teaches you a great deal about good web development, so you get to pick that up along the way – this in itself is pretty priceless. You will need to learn Ruby and Rails, though (and I assume you already have a working knowledge of HTML and CSS). You could get by with a little Ruby, as Rails does simplify many things – but learning Ruby is the only way to become a Rails Ninja, because Rails is Ruby, underneath it all.

If I’ve wet your appetite and you’re eager to learn but don’t know where to start or how to go about it, keep an eye out for a future blog post (Edit: the future is now! Link added…) where I will be doing a ‘Best way to learn Ruby & Rails‘ feature. In the meantime, here’s some quick tips:

  • If you’re new to programming go through Learn to Program by Chris Pine – a lovely introduction to OOP and Ruby.
  • Then do the excellent Kevin Skoglund, Ruby, and Ruby on Rails 3 courses over atLynda.com – they are in perfect 5 to 10 minute clips and Kevin really knows his stuff… and knows how to get you to know it!
  • After that check out David A. Black’s The Well Grounded Rubyist – one of the best Ruby books I have read to date. David is a real-life teacher, and it shows. He takes nothing for granted and walks you through every bit of code in the book so you never feel like giving up. This book really is a gem and I’m sure you’ll love it every bit as much as I do.

There’s more of course, but that’s enough to get you started. If you already know HTML and a bit of CSS, you’re ready to jump right in. So dive in and unleash your creations onto the world – faster, better, and while enjoying, yes enjoying, yourself along the way too.

Source : http://astonj.com/tech/whats-so-special-about-ruby-on-rails/

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Fri, 27 Jan 2012 01:23:31 -0800 What’s special about Ruby? http://blog.41studio.com/whats-special-about-ruby http://blog.41studio.com/whats-special-about-ruby

Well let’s start with a few stand-out thoughts on Ruby:

  • Ruby is an object of beauty –> inspired & passionate developers
  • It’s elegant and concise –> a joy to work with
  • Easy to learn but very powerful –> more experienced developers
  • Is designed for programmer happiness –> all of the above

 
Before I go further, I should warn you that these are just my personal thoughts. I’m no programming guru (and relatively new to Ruby.) But, like countless others, I’ve fallen head-over-heels in lurrve with it and am extremely passionate about it (can you tell?)

Why Ruby?

So why would someone choose Ruby over any other language? Well I can’t speak for everyone else, but I can tell you why I turned to it.

In a nutshell, it felt like the closest thing we have to how a language should be written. In other words, it’s the best programming language out there. Let me rephrase that again. Ruby is the only language I came across that ticked most if not all the boxes for my requirements: it’s powerful, easy to learn, has a huge set of libraries, a vibrant community, the best web framework, and (as an unexpected bonus) is a genuine pleasure to use. Ruby was designed specifically with Programmer Happiness™ in mind. If you don’t believe me, ask its creator, Matz.

Why not Python/PHP/Java/[insert other language here]?

I think it’s important to quickly mention two of the main reasons why I think other languages fall short:

  • They are a pita to use (semicolons after every line/poor object models/ill-thought method names/using camelCaseForVariables, etc)
  • Or they just don’t have the same appeal – that something special – that Ruby does.
  • (or both)

I found Ruby because other languages either drove me away through their idiosyncrasies, convoluted or awkward ways, or because they just didn’t posses the special qualities that makes Ruby stand out. Qualities such as the best web framework (Ruby on Rails), a huge set of libraries, a vibrant community, etc. (As detailed above in ‘Why Ruby?’)

I wasn’t going to talk about other languages too much, but a few people have asked for code comparisons, so here they are. (Python code provided by @excid3, PHP code by @citalan.)

PHP

class Ball
{
    private $_colour;

        public function __construct($colour)
    {
        $this->_colour = $colour;
    }

        public function is_red()
    {
        return ($this->_colour == 'red' ? true : false);       
    }
}

$the_ball = new Ball('green');
echo ($the_ball->is_red() ? '' : 'The ball is not red');

Python

class Ball:
    def __init__(self, colour):
        self.colour = colour

            def is_red(self):
        return self.colour == "red"

        the_ball = Ball("green")

if not the_ball.is_red():
    print "The ball is not red"

Ruby

class Ball
  def initialize(colour)
    @colour = colour    
  end

    def is_red?
    @colour == "red"
  end
end

the_ball = Ball.new("green")
puts "The ball is not red" unless the_ball.is_red?

Notice how clear and concise the Ruby code is? At a glance you quickly see what’s going on – the do ends provide excellent visual boundaries. Not too bare (like Python) but not convoluted like PHPs endless semicolons and brackets either. It strikes the perfect balance. If you really wanted to, you could even write the same code like this:

class Ball
  def initialize(colour); @colour = colour; end
  def is_red?; @colour == "red"; end
end

the_ball = Ball.new("green")
puts "The ball is not red" unless the_ball.is_red?

or even like this – without parentheses:

class Ball
  def initialize colour; @colour = colour; end
  def is_red?; @colour == "red"; end
end

the_ball = Ball.new "green"
puts "The ball is not red" unless the_ball.is_red?

Most people stick with the original tho – perhaps without parentheses when it’s more appropriate (such as when using Rails or DSLs).

So what is special about Ruby?

Oh boy, where do I start? It’s clean, uncluttered and has an air of grace and elegance. No trailing semicolons. No need for parentheses for method calls (or definitions) …even hashes don’t need them if they’re the last argument in a call. Ruby is just so refreshing.

Once you get past how gorgeous Ruby code looks, you begin to read it. Ruby’s syntax is clear and concise, and there’s nearly always more than one way of doing something. These nuances matter because they give the language a natural feel – when you read Ruby, it reads better, moreso than what you might be used to in other languages.

Ok so maybe you think all that’s superficial (for the record… it’s not!) but either way – there’s a lot more going on under the hood.

Ruby is a ‘proper’ object orientated language. In fact, almost everything in Ruby is an object. Even classes (being an instance of the class Class.) Each object belongs to the class it was instantiated from, and… it even has it’s very own class, an Eigenclass (sometimes called the Singleton class). This is cool because it means individual objects, can truly be, er, individual! (You can give objects methods that other objects of the same class don’t have.)

You can ‘mix-in’ modules into your classes. Modules are like classes (actually, classes are descended from modules) with the main difference being that you can’t instantiate an object directly from them. A class can include as many modules as you want it to, so they are a great way to organise your code and share functionality between classes. They’re also handy for namespacing (so your class names are less likely to clash with someone else’s).

Ruby also gives us open classes, where you can reopen a class at any point and just add to it. You can even do this to standard classes, such as the String class – how many languages let you do that huh!? You could actually go on to modify existing code. Don’t like how a method works? No problem, change it! This is often referred to as monkey patching – something that often scares people from other languages. But that’s Ruby – it treats you as a grown-up, and lets you decide how responsible (or ruthless!) you want to be.

Ruby also gives us code blocks which are great for (amongst other things – such as DSL’s) closures – although we also get bindings for that. Duck typing means we don’t have to declare types beforehand and syntactic sugar lets us create setter methods like this:

def name=(x)
 name = x
end

Where ‘name=’ is the name of the method. Remember that parentheses are optional in Ruby? Well that, and the fact that Ruby lets us use an equals sign in our methods (as shown above) allows us to go on and do this:

name = "AstonJ"

It ignores the space between the equals sign and the rest of the method. Pretty cool, no? And that’s just scratching the surface – there’s loads more on offer!

Ruby also gives us powerful tools and tricks like introspection, dynamic methods, ghost methods, mimic methods, class macros and the creation of classes, methods and other code on-the-fly – something you might have heard of as metaprogramming: code that writes code. We also get proc objects (in a number of flavours) and all the usual stuff you’d expect, such as Arrays, Strings, Hashes, and a lot of others you might not, like method missing, class eval, bang methods and more! And that’s just the language itself!

The community

Here I’ll just copy and paste what I wrote in a previous post (What’s special about Ruby on Rails) as pretty much the same applies here.

The Ruby community rocks. You get the feeling everyone is on the same wavelength, most Rails devs seem to use OS X and TextMate for example (even down to the same ‘theme’!) but the conventions run a lot deeper. Whether it’s indentation style or using parentheses in your method definitions or calls (they’re optional in Ruby) there’s a ‘Ruby way’ and most in the community stick to it. It’s not because Ruby users are mindless zombies mind you, it’s because we genuinely like the same things and have similarly high standards.

The most important thing however, is how passionate and helpful the community is. Good enough just isn’t good enough. That’s why test driven development (TDD) is such a big thing in the Ruby community, and why you can rest assured that your peers will always help you stay on top of your game.

As you might expect, with something so cherished at its heart, the community are eager to help each other get the best out of it. Testament to this are all the resources that are not only free but have clearly taken a lot of time and effort to put together. Here’s a quick list:

  • tryruby.org – where you get to try (and learn) Ruby in your browser
  • the extremely enjoyable Rails for Zombies where the Envy Labs team take you through some gory screencasts then test your knowledge via the brain browser
  • the fantastic Railscasts which is nearly as old as Rails itself (!)
  • Rails Tutorial which is an excellent step-by-step that helps you build a twitter clone.
  • the IRC #rubyonrails channel (irc.freenode.net) where there’s always some cheery soul willing to lend a helping hand
  • the utterly brilliant Ruby Mendicant University (and Ruby Best Practices from the same person, Gregory Brown).
  • Finally I just have to include Rails Hotline where if you get stuck and fancy talking to someone who might be able to help, you can – for free!

Pretty awesome don’t you think? And did I mention they are all free!?

If all of that isn’t enough for you (it should be, but if it isn’t…) then there’s one last thing that I find quite remarkable. I’m fairly new to Ruby, yet many leading or well known figures in the community have taken time out to speak to me. Yehuda Katz talked to me at length about learning Rails. Gregg Pollack was happy to discuss my ideas of where Rails for Zombies could lead. Ryan Bigg made the effort to get a .mobi version of his book (Rails 3 in Action) to me as he was keen on hearing my thoughts, and even DHH (the creator of Rails) has discussed totally unrelated topics via Twitter. And that’s just the people who I know of who are leading figures! I’ve also exchanged tweets with a number of others but won’t include them here for brevity – well apart from Russ Olsen, the author of two of my favourite Ruby books (Design Patterns in Ruby and Eloquent Ruby) who is following me on Twitter. *Faints

It’s fantastic that a large number of people high up in the community are willing to take time out for the nubes. Is there any wonder why the community is as cool as it is?

I’d quickly like to add that the community isn’t just about programmers – many Ruby related businesses are very much part of it too. Companies like Engine Yard, Heroku, 37 signals, Shopify, Envy labs, Thoughtbot, Resolve Digital and countless others who give so much back. Just recently for example, Heroku have taken on Matz (the creator of Ruby) to work on Ruby full time – how brilliant is that!?

Culture

I want to cover culture on its own, because not all of it comes from the community. Of course the Ruby community will push you towards test driven development, writing good clean idiomatic code, contributing back to Ruby or other open source projects and generally helping you become a good Ruby citizen. But some cultural aspects are inherently down to the language itself – bizarre as that might sound.

The most important, and perhaps what will (and should?) make for interesting reading for managers and the ‘enterprise’, is the culture of learning.

If you go back to my list at the start of this post, you’ll see the brief list of things that make for Ruby Programmer Happiness™ – and what do people excel at? Things they enjoy :-)

I noticed a massive difference in my desire to learn Ruby, compared to PHP. PHP totally uninspired me. Don’t get me wrong, I was as desperate to learn to program as much as I’ve ever been (maybe even moreso back then) but all I wanted to do was get through the PHP books as quickly as possible just to ‘get on with it’. I never really enjoyed PHP, therefore I didn’t enjoy learning it – and that’s a problem, because people will generally only do the minimum or just skim over stuff, never truly understanding things.

Ruby, by contrast, is something I love. I enjoy reading about it and learning as much as I can. My appetite for all things Ruby is insatiable – and I’m not exactly a geek! It is just constantly, pleasantly, surprising me, and things just seem to ‘stick’ more (that’s testament to Matz wanting to make it a ‘natural’ language) so morale is always high. Additionally, because Ruby is very natural and therefore easy to pick up, you get people from all walks of life giving it a go – and that’s brilliant because it brings in creative people that might have otherwise not got into programming at all.

This, I think, is why you get better Ruby programmers. Of a higher skill-set and with more ‘experience’ – we tend to enjoy furthering our knowledge because we enjoy the topic so much. I really can’t stress this point enough, this is the reason (which itself is only there because of all the other factors) why I believe Ruby is going to grow at a phenomenal rate – it’s because we want to, not because we have to (JS/browsers) or we’re told we should do (Java/enterprise).

Everything else

There’s so much more to cover that it would be impossible to cover everything, so I’ll try to keep this brief. Ruby on Rails is widely considered to be the best web framework (see: What’s Special about Ruby on Rails? for more info) – it’s actually what first drew me to Ruby, and like many people, “I came for Rails but stayed for Ruby”! That’s not the only web framework btw, we also have Sinatra and a heap of others too (and also plenty of CMS and blog systems).

There has been over 281 million downloads of around 28 thousand RubyGems (aka libraries). From testing frameworks to web frameworks to authentication systems to backup systems to geocoding tools to e-commerce to email processing – chances are if you’re trying to do something there’s a gem out there that does it!

We also have lots of great learning material – what good is all that power if you’re just not able to learn it effectively? And lots of companies (like Engine Yard) offer sponsorships for training courses (or there’s even the Ruby University which I mentioned earlier).

Hopefully you’re beginning to get an idea why Ruby is special (and there’s a lot I haven’t even covered – such as the various Ruby implementations, like Jruby, Rubinious, MacRuby). Along with the beauty of language itself, we have all these other things – and they all add up to make Ruby the first class package that it is.

Conclusion

A programming language that inspires people is rather special – and Ruby is one that truly does just that. Add in its power, simplicity and elegance and you have a compelling package. One that will help you in work and play – and often blur the line between the two. Wouldn’t you want to get paid to do something you enjoy? I’m not kidding when I say that’s exactly how it is for almost all Rubyists I know – yet another reason why Ruby is special, for you, your boss, your client, and maybe even the world. (Well maybe!)

Where next?

So have I convinced you? If so keep an eye out for an upcoming post (Edit: link added…) where I’ll detail the best way to learn Ruby (& Rails) - but until then, be sure to check out the following

  • If you’re new to programming, I urge you to go through Learn to Program by Chris Pine – it’s a lovely introduction to OOP and Ruby.
  • If you have some programming experience, then do the excellent Kevin Skoglund Ruby course over at Lynda.com – they are in perfect 5 to 10 minute clips and Kevin really knows his stuff… and knows how to get you to know it!
  • After that, check out David A. Black’s The Well Grounded Rubyist – one of my all-time favourite Ruby books. David is a real-life teacher, and it shows. He takes nothing for granted and walks you through every bit of code in the book so you never feel like giving up.
  • And after that, get Russ Olsen’s Eloquent Ruby – another firm favourite. Russ is a very experienced programmer of a number of different langauges and he really helps you understand the ‘Ruby way’. When I read this book, I used the highlight function on my Kindle so much that in the end I thought ‘forget that – I might as well re-read the book later’ because I am pretty much highlighting it all anyway!

Don’t forget, keep an eye out for my How to Learn Ruby & Rails post – doing everything I list there will help you become fairly proficient in next to no time.

Good luck – and I hope to welcome you into the Ruby community soon!

Source : http://astonj.com/tech/whats-special-about-ruby/

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 26 Jan 2012 23:03:00 -0800 LineCache - A module to read and cache file information of a Ruby program http://blog.41studio.com/linecache-a-module-to-read-and-cache-file-inf http://blog.41studio.com/linecache-a-module-to-read-and-cache-file-inf
== SYNOPSIS

The LineCache module allows one to get any line from any file, caching
the lines and file information on first access to the file. Although
the file may be any file, the common use is when the file is a Ruby
script since parsing of the file is done to figure out where the
statement boundaries are.

The routines here may be is useful when a small random sets of lines
are read from a single file, in particular in a debugger to show
source lines.

== Summary

  require 'linecache'
  lines = LineCache::getlines('/tmp/myruby.rb')
  # The following lines have same effect as the above.
  $: << '/tmp'
  Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb')

  line = LineCache::getline('/tmp/myruby.rb', 6)
  # Note lines[6] == line (if /tmp/myruby.rb has 6 lines)

  LineCache::clear_file_cache
  LineCache::clear_file_cache('/tmp/myruby.rb')
  LineCache::update_cache   # Check for modifications of all cached files.

== Credits

  This is a port of the module of the same name from the Python distribution.

  The idea for how TraceLineNumbers works, and some code was taken
  from ParseTree by Ryan Davis.

== Other stuff

Author::   Rocky Bernstein <rockyb@rubyforge.net>
License::  Copyright (c) 2007, 2008 Rocky Bernstein
           Released under the GNU GPL 2 license

== Warranty

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

$Id$Source : https://github.com/mark-moseley/linecache

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 26 Jan 2012 20:14:23 -0800 Creating More Using Less Effort with Ruby on Rails http://blog.41studio.com/creating-more-using-less-effort-with-ruby-on http://blog.41studio.com/creating-more-using-less-effort-with-ruby-on

 

Creating More Using Less Effort with Ruby on Rails

If you build websites, you have no doubt heard about Ruby on Rails (RoR). But if you’re a designer or front-end developer or you’re using PHP without any application framework, it may seem like a big leap to adopt the Ruby on Rails approach. In this article, I hope to demystify Ruby on Rails and convince you that you can make the leap—and that it is a leap worth making if your needs fit within the Ruby on Rails “sweet spot” detailed below.

It does take time to learn new ways to do all the things you already know how to do, and to learn some new concepts and techniques at the same time. In the short term, switching technologies, even to Ruby on Rails, will destroy your productivity. Nevertheless, I’m convinced that many web developers would be more productive, produce better sites, and even have more fun if they took the leap and began using Ruby on Rails.

Fun for the whole family

Ruby on Rails (Rails for short) is a “full-stack” framework, which means that it covers both front-end and back-end design. This makes it an exceptionally potent tool in the hands of a “jack-of-all-trades” developer. Even if you’re primarily a front-end or a back-end developer, though, you can still use Ruby on Rails effectively. The interfaces between the front end (the browser’s HTML, CSS, and JavaScript) and the back end (Ruby, and the Rails framework) are well defined, so you don’t need to understand both sides if you want to focus on one or the other.

If you’re a web designer or front-end developer, you can learn how to use the Ruby on Rails template system, and how to write little bits of embedded Ruby code in your view files. This will make you a much better partner for a back-end developer, since you can work directly on the Rails application files instead of delivering HTML and CSS that someone else has to integrate.

So whether you’re approaching Ruby on Rails as a front-end or back-end developer, on which projects should you consider using it?

The “sweet spot”

Ruby on Rails is at the heart of diverse web applications and sites such as Basecamp, Blinksale, 43Things, Odeo, Revolution Health, Twitter, YellowPages.com, and A List Apart. The enthusiasm for Rails extends to many of the largest web companies. Yahoo, eBay, Amazon, and AOL all have Ruby on Rails projects, and ThoughtWorks is creating enterprise applications in Rails. But for all the diversity of Ruby on Rails applications, the ones that are best-suited to the framework have a few key things in common.

A website or web service is most appropriately implemented with Ruby on Rails when it has the following three characteristics:

  • It is a database-backed website or web service large enough to justify the overhead of a powerful framework.
  • It has unique needs that aren’t well met by a typical CMS. (If Joomla or Drupal does everything you need, such systems may be a better choice.)
  • It is a new application, allowing developers to start fresh with the database and software architecture.

This is the “sweet spot” for Ruby on Rails applications. Applications that share these characteristics can probably be built much more quickly with RoR than with PHP, .NET, or Java, once the investment required to learn Rails has been made.

Productivity boosts

One of the main reasons Ruby on Rails increases productivity is that it makes building new applications, adding features, and making tweaks much easier. The combination of the language (Ruby) and the framework (Rails) means you can do more with less code. Less code--and better-structured code--means changes are relatively painless, so you can iterate and experiment more readily. This leads to better sites, and, hopefully, more fun building them.

Of course, adopting a major new tool requires an investment of time that can’t be taken lightly. If you’re focused on a single project, it often isn’t justifiable. But if you expect to keep building websites for some time, and you’re building sites of significant complexity, a short-term investment in learning Ruby on Rails will pay off in the long term.

To understand why I believe you can do more with less effort using Ruby on Rails, let’s start with a quick look at Ruby.

Meet Ruby

Ruby is a modern, object-oriented language. In any Ruby program, everything is an object. Ruby is also a dynamic language, which means a variety of things:

  • Ruby is interpreted dynamically (like PHP), so there is no compilation (as there is with C or Java.) This speeds up iterative development.
  • In Ruby, variables are dynamically assigned a type when they are used, eliminating all the code you must write in most other languages to define and set up variables.
  • A Ruby program can generate code dynamically, modifying itself as it executes. Rails uses this capability internally to deliver its “magic,” which you can simply enjoy. (You don’t need to understand how these techniques work.)

Ruby is a wonderfully clean language to read and write, but its benefits go beyond that. Because Ruby can be powerfully extended, the Rails framework is able to turn it into a sort of special-purpose language for building web applications.

While Ruby (a language) and Rails (a framework) are separate things, they complement and depend on each other in many ways. All Ruby on Rails applications are written in Ruby, and the character of Ruby has a big influence on Ruby on Rails applications. There are frameworks, such as CakePHP, that bring many of Rails’ ideas to other languages. But the power and flexibility of Ruby makes Rails cleaner and more flexible than many other frameworks. If you’re going to make the investment in learning a framework, learning Ruby while you’re at it isn’t that big a hurdle, and the payoff is considerable.

The Rails approach

Many websites are built without any application framework at all: you just write the code you need and borrow bits from various places when you can. That’s fine for small sites, but it can quickly get out of control, resulting in reams of messy code that is hard to understand and to maintain.

With a framework such as Ruby on Rails, a lot of decisions about how to structure your code are already made for you and you also have a powerful set of libraries at your disposal.

Another important characteristic of Rails is that it organizes each application around a model-view-controller (MVC) structure. MVC, a well-established pattern for organizing software projects, gives all your code a consistent structure, which helps a lot when you’re working on multiple sites, or bringing in someone new to work on a site. It also provides separate files, with clean interfaces, that can be split between front-end and back-end developers.

Databases and objects

Ruby on Rails is designed to be used to build database-backed applications, and many of its core components focus on interacting with databases. The heart of Rails is a library called Active Record, which implements something called object-relational mapping (ORM). With ORM, you can work with software objects that represent your data and let the Active Record library take care of communicating with the database.

This may sound mysterious in the abstract, so let’s make it concrete. Even without knowing any Ruby--or anything about object-oriented programming--I bet you can make sense out of the following code examples, which are pieces of actual Ruby on Rails code.

Suppose you have a bookstore site and you want to add a new book. You could write:

newbook = Book.new

You’re telling the “Book” class that you want an empty book object, named “newbook.” You can set the title, or any of its other attributes, in an intuitive way:

newbook.title = "Angle of Repose"
newbook.author = "Wallace Stegner"

At this point, you have an object in memory. All it takes is:

newbook.save

...and your new book has been written to the database. Active Record generates the SQL to tell the database to insert the record. You can add validations on all the fields and generate descriptive error messages with just a few more lines of code.

Now you want to find that book out of the millions in your database. Just write:

angle_of_repose = Book.find_by_title "Angle of Repose"

...and you have an object, which you’ve named “angle_of_repose,” that has all the information from the appropriate database record.

There’s a little more to it, but not that much; working with software objects that reflect the information your site deals with is a natural and powerful approach. In RoR, you have a rich set of software objects that correspond to your database tables, and these objects make up the “model” layer of the model-view-controller system.

Your code interacts with the model objects, and Active Record creates the SQL to make the database do what you want. You don’t have to write any SQL to work with the database. And since none of your code communicates directly with the database, you can switch from one database engine to another by simply changing a configuration setting.

Views and controllers

To create web pages, Rails provides a template system that makes it easy to use consistent page structures, to insert common components without repeating their code, to render information that comes from the database, and to display and process forms. These templates constitute the “view�? layer of the model-view-controller system.

If you’re a front-end developer, this is the part of Rails you should focus on. You can simply assume that your “view file” will be handed variables that contain whatever information you need to display. Just as PHP files are a mix of PHP code and HTML, a typical Rails view is a mix of Ruby and HTML. Continuing with our bookstore example, here’s a snippet of view code that displays the title and author of a book:

 

<%= book.title %>

 

<%= book.author %>

The Ruby code is marked by <%= and %>; the rest is HTML. The HTML and the output of the Ruby code are combined to create the web page.

Rails has integrated support for the Prototype and Scriptaculous JavaScript libraries, plus a great facility called Ruby JavaScript (RJS), for building Ajax interfaces. You can write almost everything in Ruby, including code that is eventually executed by the browser as JavaScript (the Rails framework handles the translation.)

A “controller” is a piece of Ruby code whose primary job is to communicate with the model to prepare the data needed by the view. Any information that the view needs is assembled by the controller in a set of variables before invoking the view. The controller also responds to Ajax requests after the page has loaded. Controllers provide a variety of other functions as well, from user authentication to error handling.

“Convention over Configuration”

Rails tries hard to provide reasonable defaults for almost everything. Following a philosophy called Convention over Configuration, Rails almost entirely eliminates configuration files.

If you follow the Rails conventions, an amazing amount of stuff, from routing requests to the correct controller and view, to validating form data and displaying error messages, just works. Compared with most other languages and frameworks, it takes less code to accomplish most common tasks.

The Convention over Configuration approach is sometimes frustrating for newcomers, especially if they try to learn from an existing application, because there are hidden assumptions behind much of the code. The assumptions are what make the code simpler, but they can be confusing when you don’t know them. After you learn the Rails conventions, though, everything in Rails makes more sense. And when you’re building a new site, you have the wind at your back, because so much is already defined for you.

It’s not perfect

Rails does have its drawbacks. These weak points are minimized for applications that fall within the Rails sweet spot I described earlier, but they can be big issues at the fringes.

Ruby is slower than most other languages. This is likely to change this year, but for now, it is a disadvantage--for those few applications in which processing time is actually an issue. In reality, this is a non-issue for the vast majority of websites.

The overhead of the MVC framework can also slow things down. With a little attention, though, most Rails applications can be made to perform very well. Model requests often need tuning to reduce the number of database accesses required. You can often eliminate database requests entirely: Rails includes a powerful caching system, so pages can frequently be created once and delivered many times.

Rails applications are also more trouble to host than PHP applications. Because of the size of the Rails framework code, it has to be kept in memory all the time, not loaded in response to a request. You need 100–200 MB of dedicated RAM to host even a low-traffic Rails application. With PHP applications, in contrast, you can host hundreds of applications on a single server, because they don’t occupy any memory when they aren’t being accessed.

Because of these server requirements, shared hosting of Rails applications is generally problematic. A VPS (virtual private server) is usually the best choice. Setting up a Rails server can be more complex than for PHP. This was an issue a year or two ago, but now there are many Rails-oriented hosting companies that provide turnkey solutions.

Another result of these server requirements is that Ruby on Rails hosting tends to be more expensive than for other platforms and languages. If you’re in the Rails sweet spot, your application is significant enough that the incremental hosting cost is insignificant compared to the value you get from using Rails.

The learning curve

The complexity of Rails can make it hard for a beginner to get started: it takes months to become familiar with all of Rails. But you can get started by first learning just enough to build a basic Rails site. As you begin working with it, you’ll pick up new skills and knowledge as you need it.

People come to building websites in various ways and from different backgrounds, but most of them fall into one of two categories:

  • People who have an idea for a site they want to build and learn just enough technology to build it.
  • Programmers who see websites as just another kind of program.

Ruby on Rails was built by programmers, for programmers. So if you come to it from a professional software development background, it will feel a lot more familiar than if you come from web design.

If you’re not a software developer, there’s more to learn, but it’s not beyond your reach. Learning the parts of Ruby, and some bits of object-oriented programming, that you need to know to use Rails is not difficult. To start building applications using the Rails framework you only need to know how to use a limited subset of Ruby’s capabilities.

You can leave the advanced Ruby coding to those who work on the framework itself. You don’t need to understand much about how the internals of Rails works, or the techniques (such as metaprogramming) that it uses internally.

The Rails ecosystem includes many practices that come from the software development world, including use of source-code control systems, an automated testing framework, documentation tools, and deployment scripts. If you’ve been doing ad-hoc web development, these may be foreign concepts, but they can bring a lot of sanity into your work life once you become comfortable with them.

What to learn when

The art of learning Rails is figuring out just what you can ignore at which stage of your education so you can grapple with a few things at a time, instead of with all the diverse technologies that make up a Rails application. (One easy way to get started learning Ruby on Rails is with the "free online course":http://www.BuildingWebApps.com/learning_rails produced by the author of this article.)

Start by learning the basics of Ruby. You don’t need to go too deep, but you need to know the basics before you can effectively develop with Rails. Rails code looks almost like markup, and it is tempting to think of it as such, but you need to make the shift to thinking of your site as a program that emits web pages, rather than as a set of files that are web pages.

If you’re focused on the front end, learn how layouts, view templates, and partials work. If you’re working with a back-end developer, they’ll take care of the model and controller layers and provide your views with variables packed with just the data you need.

At first, you can ignore Ajax; it’s a largely separate layer that can make a big improvement in the user experience, but it really is optional. So you can put RJS, Prototype, and Scriptaculous aside when you’re learning Rails. Add on a layer of Ajax sophistication once you’re comfortable with the basics.

If you’re a back-end developer, concentrate on learning how to model your application domain as a set of resources, create your database tables, and use the resulting objects. The Rails framework is wide and deep, so it takes time to learn thoroughly, but you don’t need to use very much of it to get started.

While you’re learning Rails, you can ignore testing and all its associated complexities, even though it gets a lot of attention in discussions of Rails. When you’re further along, come back to it--but don’t let it slow down your initial learning or add to your cognitive load.

And you’re off!

Once you’re up to speed, Ruby on Rails will become an old friend. With this powerful set of tools at your fingertips, you’ll be more productive than ever.

By being able to do more with less code, you’ll build better sites and have more fun doing it. There’s no looking back.

Illustration by Kevin Cornell

Source : http://www.alistapart.com/articles/creatingmoreusinglesseffortwithrubyonrails/

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 26 Jan 2012 01:35:51 -0800 How to Pass Params to Named Scope in Rails http://blog.41studio.com/how-to-pass-params-to-named-scope-in-rails http://blog.41studio.com/how-to-pass-params-to-named-scope-in-rails

Hi guys :)

In my previous post create named scope in rails, I told you about named scope in rails, what excess of named scope,how to create and how to use it. Now i will tell you, how to pass params to named scope in rails. For example, we will search users by user_name, first_name, last_name, email and city. Most of us, will create in the controller like this :

 

1
2
3
4
5
6
class UsersController < ApplicationController
  def search
      @users = User.where(["user_name LIKE ? OR first_name LIKE ? OR last_name LIKE ? OR email LIKE ? OR city LIKE ?",
      "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%"])
  end
end

 

That’s will work correctly, but that’s not recomended by rails development. I think the best way to do it is to create named scope and pass the params to named scope. Please look below, how to pass params to named scope in rails.

In user model :

1
2
3
4
5
class User < ActiveRecord

   scope :search, lambda{|keyword| where(["user_name LIKE ? OR first_name LIKE ? OR last_name LIKE ? OR email LIKE ? OR city LIKE ?",
      "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%"])}
end

In user controller :

1
2
3
4
5
class UsersController < ApplicationController
  def search
      @users = User.search(params[:keyword])
  end
end

Source : http://whatisrubyonrails.com/how-to-pass-params-to-named-scope-in-rails

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Thu, 26 Jan 2012 00:25:23 -0800 How to Create Named Scope in Rails http://blog.41studio.com/how-to-create-named-scope-in-rails http://blog.41studio.com/how-to-create-named-scope-in-rails

Named scope used to specify commonly used sql queries which can be define as method on model or on the association objects. With named scope, you can use every that have been included ActiveRecord method such us joins, select, where and etc.

Most of us start out writing our queries directly in the controllers, like this :

1
2
3
4
5
6
class  ArticleController < ApplicationController

  def article_today
    @articles = Article.where(["created_at > ?", Time.now.beginning_of_day])
  end
end

That’s works, but it’s broken cardinal role of Rails development. Rather than we embedding sql query in our controller to find article which created today in our site, much better to write something code called named scope in model which would return a collection of Article objects. To create a scope, we use the named_scope method in Rails 2 and scope method in Raials 3 above inside the class model.

Rails 2 :

1
2
3
4
class Article < ActiveRecord::Base

 named_scope :today, where(["created_at > ?", Time.now.beginning_of_day])
end

Rails 3 above :

1
2
3
4
class Article < ActiveRecord::Base

 scope :today, where(["created_at > ?", Time.now.beginning_of_day])
end

Then in our controller we call :

1
2
3
4
5
calss ArticlesController < ApplicationController
 def article_today
 @articles = Article.today
 end
end

That’s would return a collection of Article objects which created today. It’s look DRY query. In addition we also use scope to get object with join table. Please look below :

Rails 2 :

1
2
3
4
5
class User < ActiveRecord::Base
 has_many :addresses

 named_scope :group_by_city, joins(:addresses).where(["addresses.city = ?", "Jakarta"])
end

Rails 3 above :

1
2
3
4
5
class User < ActiveRecord::Base
 has_many :addresses

 scope :group_by_city, joins(:addresses).where(["addresses.city = ?", "Jakarta"])
end

Source : http://whatisrubyonrails.com/create-named-scope-in-rails

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Wed, 25 Jan 2012 23:04:00 -0800 How to Connect to Multiple Database in Rails http://blog.41studio.com/how-to-connect-to-multiple-database-in-rails http://blog.41studio.com/how-to-connect-to-multiple-database-in-rails

I have problem in build rails application that how to connect to multiple database in rails. After I searching i found how to fix my problem in here and in Rails Recipe B3 ebook.

By default Rails have a connection to one database per aplication. But if you want to connect to multiple databse, it’s very simple in rails. To create connection to multiple database in a rails application, we must set up named connection in database configuration(database.yml), configure model, and use inheritance to safely allow multiple models to use the new named connection.

In this case we have scenario like this :

 

connect to multiple database in rails

OK, let’s create a new rails application with mysql databse :

1
rails new multiple_database –database=mysql

In this case I use rails 3.1, but I think this same way in rails 3.0

Configure databse.yml to be like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: multiple_database_development
  pool: 5
  username: root
  password: root
  socket: /var/run/mysqld/mysqld.sock

external_development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: multiple_database_external
  pool: 5
  username: root
  password: root
  socket: /var/run/mysqld/mysqld.sock

Now create database whit this command line :

1
rake db:create:all

Create article and comment model :

1
2
rails g model article title:string content:text
rails g model comment article_id:integer name:string content:text

Open article model, and edit to be like this :

1
2
3
class Article < ActiveRecord::Base
  has_many :comments
end

Open comment model, and edit to be like this :

1
2
3
4
class Comment < ActiveRecord::Base
  establish_connection("external_development") #external_development is a named configuration in database.yml
  belongs_to :article
end

Open create_comment migration file and add this section above def self.up in rails 3.0 or def change in rails 3.1:

1
2
3
def connection
    Comment.connection
end

so it becomes like this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CreateComments < ActiveRecord::Migration

  def connection
    Comment.connection
  end

  def change
    create_table :comments do |t|
      t.integer :article_id
      t.string :name
      t.text :content

      t.timestamps
    end
  end
end

Note : Comment.connection is a method to determine which database is used in migration as it has been declared in comment model.

Don’t forgate migrate file to database:

1
rake db:migrate

 

Open rails console, and chek connection :

create article

1
article = Article.create(:title => "First Article", :content => "Content of first article")

create comment

1
comment = article.comments.create(:name => "Dan", :content => "this is comment content")

 

Check database connection :

Article Connection

1
Article.connection.current_database

will be return :

1
=> "multiple_database_development"

Comment Connection

1
Comment.connection.current_database

will be return :

1
=> "multiple_database_external"

Now we can see that different database used. Article model use “multiple_database_development” database and comment model use “multiple_database_external” database.

Source : http://whatisrubyonrails.com/how-to-connect-to-multiple-database-in-rails

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Wed, 25 Jan 2012 20:45:00 -0800 Tips to install ruby 1.9.3 using rvm http://blog.41studio.com/tips-to-install-ruby-193-using-rvm http://blog.41studio.com/tips-to-install-ruby-193-using-rvm

If you want to install ruby 1.9.3 using rvm, maybe you typing like this:

rvm install 1.9.3

This way will give you errors when install ruby 1.9.3, but if you using this way you maybe not find any errors:

sudo apt-get install libyaml-ruby
rvm get latest
rvm reload
rvm rvmrc trust
rvm install ruby-1.9.3-p0
rvm rubygems latest

Well, I hope these tips can help you all :)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio
Wed, 25 Jan 2012 20:42:08 -0800 cocoon http://blog.41studio.com/cocoon http://blog.41studio.com/cocoon

cocoon is a Rails3 gem to allow easier handling of nested forms.

Nested forms are forms that handle nested models and attributes in one form. For example a project with its tasks, an invoice with its ordered items.

It is formbuilder-agnostic, so it works with standard Rails, or Formtastic or simple_form.

Prerequisites

This gem uses jQuery, it is most useful to use this gem in a rails3 project where you are already using jQuery.

Furthermore i would advice you to use either formtastic or simple_form.

I have a sample project where I demonstrate the use of cocoon with formtastic.

Installation

Inside your Gemfile add the following:

gem "cocoon"

Rails 3.1

Add the following to application.js so it compiles to the asset_pipeline

//= require cocoon

Rails 3.x

If you are using Rails 3.0.x, you need to run the installation task (since rails 3.1 this is no longer needed):

rails g cocoon:install

This will install the needed javascript file. Inside your application.html.haml you will need to add below the default javascripts:

= javascript_include_tag :cocoon

or using erb, you write

<%= javascript_include_tag :cocoon %>

That is all you need to do to start using it!

Usage

Suppose you have a model Project:

rails g scaffold Project name:string description:string

and a project has many tasks:

rails g model Task description:string done:boolean project_id:integer

Edit the models to code the relation:

class Project < ActiveRecord::Base
  has_many :tasks
  accepts_nested_attributes_for :tasks, :reject_if => :all_blank, :allow_destroy => true
end

class Task < ActiveRecord::Base
  belongs_to :project
end

What we want to achieve is to get a form where we can add and remove the tasks dynamically. What we need for this, is that the fields for a new/existing task are defined in a partial view called _task_fields.html.

We will show the sample usage with the different possible form-builders.

Using formtastic

Inside our projects/_form partial we then write:

- f.inputs do
  = f.input :name
  = f.input :description
  %h3 Tasks
  #tasks
    = f.semantic_fields_for :tasks do |task|
      = render 'task_fields', :f => task
    .links
      = link_to_add_association 'add task', f, :tasks
  -f.buttons do
    = f.submit 'Save'

and inside the _task_fields partial we write:

.nested-fields
  = f.inputs do
    = f.input :description
    = f.input :done, :as => :boolean
    = link_to_remove_association "remove task", f

That is all there is to it!

There is an example project on github implementing it called cocoon_formtastic_demo.

Using simple_form

This is almost identical to formtastic, instead of writing semantic_fields_for you write simple_fields_for.

There is an example project on github implementing it called cocoon_simple_form_demo.

Using standard rails forms

I will provide a full example (and a sample project) later.

How it works

I define two helper functions:

link_to_add_association

This function will add a link to your markup that will, when clicked, dynamically add a new partial form for the given association. This should be placed below the semantic_fields_for.

It takes four parameters:

  • name: the text to show in the link
  • f: referring to the containing form-object
  • association: the name of the association (plural) of which a new instance needs to be added (symbol or string).
  • html_options: extra html-options (see link_to) There are three extra options that allow to control the placement of the new link-data:
    • data-association-insertion-node : the jquery selector of the node
    • data-association-insertion-method : jquery method that inserts the new data. before, after, append, prepend, etc. Default: before
    • data-association-insertion-position : old method specifying where to insert new data.
      • this setting still works but data-association-insertion-method takes precedence. may be removed in a future version.

Optionally you could also leave out the name and supply a block that is captured to give the name (if you want to do something more complicated).

link_to_remove_association

This function will add a link to your markup that will, when clicked, dynamically remove the surrounding partial form. This should be placed inside the partial _<association-object-singular>_fields.

It takes three parameters:

  • name: the text to show in the link
  • f: referring to the containing form-object
  • html_options: extra html-options (see link_to)

Optionally you could also leave out the name and supply a block that is captured to give the name (if you want to do something more complicated).

Inside the html_options you can add an option :render_options, and the containing hash will be handed down to the form-builder for the inserted form. E.g. especially when using twitter-bootstrap and simple_form together, the simple_fields_for needs the option :wrapper => 'inline' which can be handed down as follows:

= link_to_add_association 'add something', f, :something, :render_options => {:wrapper => 'inline' }

Callbacks (upon insert and remove of items)

There is an option to add a callback on insertion or removal. If in your view you have the following snippet to select an owner (we use slim for demonstration purposes)

#owner
  #owner_from_list
    = f.association :owner, :collection => Person.all(:order => 'name'), :prompt => 'Choose an existing owner'
  = link_to_add_association 'add a new person as owner', f, :owner

This view part will either let you select an owner from the list of persons, or show the fields to add a new person as owner.

The callbacks can be added as follows:

$(document).ready(function() {
    $('#owner').bind('insertion-callback',
         function() {
           $("#owner_from_list").hide();
           $("#owner a.add_fields").hide();
         });
    $('#owner').bind("removal-callback",
         function() {
           $("#owner_from_list").show();
           $("#owner a.add_fields").show();
         });
});

Do note that for the callbacks to work there has to be a surrounding container (div), where you can bind the callbacks to.

Control the Insertion behaviour

The default insertion location is at the back of the current container. But we have added two data-attributes that are read to determine the insertion-node and -method.

For example:

$(document).ready(function() {
    $("#owner a.add_fields").
      data("association-insertion-method", 'before').
      data("association-insertion-node", 'this');
});

The association-insertion-node will determine where to add it. You can choose any selector here, or specify this (default it is the parent-container).

The association-insertion-method will determine where to add it in relation with the node. Any jQuery DOM Manipulation method can be set but we recommend sticking to any of the following: before, after, append, prepend. It is unknown at this time what others would do.

Partial

The partial should be named _<association-object_singular>_fields, and should start with a container (e.g. div) of class .nested-fields.

There is no limit to the amount of nesting, though.

Note on Patches/Pull Requests

  • Fork the project.
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.

Todo

  • add more sample relations: has_many :through, belongs_to, ...
  • improve the tests (test the javascript too)(if anybody wants to lend a hand ...?)

Copyright

Copyright (c) 2010 Nathan Van der Auwera. See LICENSE for details.

Source : https://github.com/nathanvda/cocoon

 

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/1576685/276973_184807401581078_2095814940_q.jpg http://posterous.com/users/cPQLWAblRTFjk 41studio 41studio 41studio