Search posterous

Search all posts and users. Type a name, type a favorite song title, whatever! See what comes up.
  

More posterous blogs











More recommended blogs »

Here are posterous posts filed under rubyonrails...

timocratic says...

So my buddy Tammer's recent post about the Gang of Four's Template Pattern reminded me of some code I saw recently. A start-up's greenfield project had it's authorization done in a pretty clean way using the template pattern. Basically every object determined what could be done to it, something like this:

After continuing this approach to fully cover CRUD you make a straight-forward set of accessors that can be used to easily enforce permissions in the controller in a programmatic way (this project was using on of the inherited resourceful-controller plugins, so that was a big plus). The developer who implemented this commented that the trade-off for this simplicity was having to look in each individual model file to figure out what a user can do overall.

I figured I liked everything about this scheme except that trade-off, and since ruby is so dynamic, why settle for almost. Why not just reopen each class in the authorization file and add the methods. You still get the simplicity and encapsulation of having the model able to determine it's own permissions, based on it's state and methods, and there is still one place to look to review/change the permissions for the whole project:

Thoughts?

Filed under: rubyonrails

jarin says...

GitHub just announced that since their move to Rackspace, they’ve completely disabled gem building (and it isn’t coming back). They’re hosting existing gems for about a year, but it’s probably a good idea to update your Rails apps before you forget.

Gemcutter is the new hotness in gem repositories, and is the new GitHub-recommended source for gems.

Here’s what you need to do:

Before:

After:

Note that on GitHub, the gems were prefixed with the GitHub username. On Gemcutter, the ‘canonical’ versions of gems often drop the prefix. Be sure to do a quick search on Gemcutter if you’re not sure.

Don’t forget to run rake moonshine:gems afterward if you’re deploying with Moonshine.

On a side note, Gemcutter is hosted on Heroku. I checked out Heroku when it first came out, and it has made an amazing transition from a gimmicky in-browser Rails editor to a full-fledged Amazon EC2-backed power hosting provider with unbelievably simple Rack app deployment. If you are still in the dark like I was up until recently, I highly recommend checking them out.

Do this before you forget, and remind your Ruby / Rails / Sinatra / Merb / etc. pals to do the same by retweeting this post! Or like, Google Wave it or something.

Filed under: Ruby on Rails

andyman says...

Here's Part 2 of my thoughts on the Aloha on Rails technical conference that I attended earlier this month. (Oct 5-6)  I want to write down what I personally got out of the conference before I forget it. I meant to do this sooner, but I've been busy applying some of what I've learned. This post covers the sessions I attended on Day 2 of the conference.

Jim Weirich's session: Grand Unified Theory of Software Design

  • Jim introduced a term called connascense, which for software design purposes means the way two pieces of code are coupled, or two things that have to change together when one of them changes, in order to preserve correctness. There are different degrees of connascence:
    • Connascence of Name (CoN): where two components use the same name to couple, such as passing named parameters within a hash, or using  the name of a method or variable to refer to the same thing.
    • Connascence of Position (CoP): where the order matters, such as the order of parameters in a method call, or where positions in arrays are hardcoded. The coupling can be made more robust by converting this down to CoN.
    • Connascence of Meaning (CoM): using values to mean something for the two components. (Like "404" error code means page not found). These can be assigned to constants to somewhat reduce to CoN, but even in the assignment of values to constants, there needs to be contranascence (where two components have to be different, in order to preserve correctness) between the values to that the same value isn't assigned to different constants that are supposed to be different.
    • Connascence of Algorithm (CoA): the two components depend on the same algorithm to work right. For example if there is a method that creates a checksum (add_check_digit) and a check method to verify that a checksum matches. Can DRY (don't repeat yourself) it out by having a separate method that does the algorithm, and having both these methods call that method. (CoA->CoN)
  • Rule of Software Locality - Within the same module, there is stronger connascence. When it is farther away, use weaker forms of connascence.
  • Rule of Degree - convert higher degrees of connascence into weaker forms.
  • Thoughts: I can see how this makes software easier to understand and more maintainable - certainly for Ruby On Rails, this seems to be the way it is evolving. I'm not sure this applies as well to lower level languages though, or when optimizing for performance. Say you want to write a highly optimized device driver, or you want the data to be as small as possible (sending an array in json using CoP and CoM, as opposed to sending a json hash), you might want to use a stronger form of connascence.
  • There were several more forms of connascence he talked about, that seem to be a bit different than the previous ones: 
    • Connascence of Timing: using mutual exclusion in race condition
    • Connascence of Execution: Depends on the order of execution
    • Connascence of Identity: getting two separate objects to represent the same logical object (two pointers to the same object)
    • Connascence of Values: constraints on the values:  in graphics, left < right, top < bottom
    • Connascence is only part of the grand unified theory of software design. There are other parts: cohesion and comprehensibility (human factor).

Chad Pytel and Tammer Saleh's session: You're Doing It Wrong
  • When refactoring (when working on a legacy code rescue project) talk with your client to see if they actually still need the feature
  • In rescues where there are no existing automated tests, write integration tests for existing behavior, and unit tests for new features
  • Webrat & Selenium are key for doing these tests
  • Add functional tests for new controllers, one at a time
  • Rake tests can be tested too by moving their methods into a model. Make the rake task skinny.
  • Rails views are composed of many parts (html, css, js, ruby). Know your rails helpers and how they change across rails releases.
  • Use the yield/content_for helpers to do page titles (the <title> tag in the head) for better MVC separation

Charles Nutter's session: JRuby From Zero to Awesome
This talk/demo was amazing! Charles gave several demos of JRuby projects that just blew me away on how easy it was to use java functionality from ruby, calling methods in a very ruby-friendly way. If I have to build new stuff on top of legacy java code, then I'll definitely consider using JRuby to do it.

Blake Mizerany's session: Forget Kindergarten, Learn to Scale
Some tips on scaling, based on cloud computing with heroku
  • Don't keep state on the local environment. Everything must be disposable.
  • Share nothing. The server is not for persistent storage of dynamic assets. (temp uploaded files)
  • Be impatient: Keep everything under 200 ms. Use caching if it is needed. Rack::Cache and Memcached
  • Procrastinate: If it takes over 200 ms, run a background job.
  • Be unfair:  handle monsters separately

Anthony Eden's session: Technical Debt - Rewrite or Refactor
  • technical debt is inevitable, so plan for it, or pay it back with interest or time
  • TATFT!
  • minimize code so you can pay back technical debt quickly
  • pair programming disseminates knowledge
  • Set aside (schedule) time to deal with technical debt
  • Tasks: 
    • get rid of cruft (commented code)
    • remove methods that are no longer invoked
    • write tests for untested code,
    • use the client to see if any more code can be thrown away
    • refactor existing monster code into smaller pieces, DRY it up
  • Candidates for rewrite: 
    • if there are no existing tests, you're very likely going to need a rewrite
    • low quality code
    • owner of code is no longer there

Corey Donohoe's session: Everything I Know About Being an Open Source Hacker I Learned From Indie Hip Hop
I learned much more about the Hip Hop community than about the Rails community from this talk. Key takeaway points for me:
  1. Meet other developers, perhaps at a local meetup, or attend 2 conferences a year
  2. Check out other developers' code on github, and post your own.

Panel discussion: Modeling Maturity
  • railsmaturitymodel.com
  • There are very different views on this. Some very strong opposing views against having a Rails Maturity Model (reminds of all the bad things of CMM)
  • Related question: How does the client know who is legit and uses best practices, and who is a charlatan?
  • Check ruby-toolbox.com for good new plugins

Benjamin Sandofsky's session: Staying Above the Ghetto
  • RoR is a luxury brand: affected by the economy, and frequently copied
  • Our values as a rails community: aesthetics, pragmatic, freedom, passion
  • Our bane: commodity developers - the kind who write corporate training sites, cheap, and don't care
  • Learn, create, share

__________

For me personally, I've got some todo's based on what I learned:

Filed under: Ruby on Rails

white says...

Rails in a Nutshell

This is the draft of upcoming O'Reilly book. Feel free to read and comment. :)

Filed under: rubyonrails

mschultz says...

An oldie but a goodie. Ryan Bates' (of Railscasts.com fame) excellent remake of David Heinemeier Hansson's original 15 minute Ruby on Rails blogging app demo.

Filed under: rubyonrails

OpenHouse says...

I have been thinking lately about how many Rails controller actions I run into that are hard to read and do not reveal the actual intent of the person that wrote the software. This can be extremely frustrating for a developer working with code that they did not originally write.

Consider the following example:

We have an Article model that has an Article Type and belongs to a User. Any time a User creates/updates an Article, a Boolean "approved" attribute is set to false.

The Article migration file might look something like this:

class CreateArticles < ActiveRecord::Migration
  def self.up
    create_table :articles do |t|
      t.string  :title, :limit => 155, :null => false
      t.text :content, :null => false
      t.integer :user_id, :null => false
      t.integer :article_type_id, :null => true
      t.boolean :approved, :default => false, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :articles
  end
end

So a simple requirement in this case might be for the site Administrator to be able to "approve" articles. The business refers to unapproved articles as "pending". To do this, we would need to find all of the Articles that have an "approved" value of false. We would also need to order the results by date to return the most recent article changes first.

Here is an example of how one could accomplish this query in the controller:

class PendingArticlesController <  ApplicationController
    def index
        @articles = Article.find(:all, :include => [:user, :article_type], :conditions => ["approved = ?", false], :order => 'updated_at DESC')
    end
end

There is nothing really wrong with the above find but there are a few things we can do to improve the code by revealing more intent and using the Projects Ubiquitous Language.

Enter named_scope:
From the Rails documentation, named_scope "Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query"

By using named_scope, we can refactor the controller code as follows:

Introduce named_scope into the Article model

class Article < ActiveRecord::Base
    named_scope :pending, :include => [:user, :article_type], :conditions => ["approved = ?", false], :order => 'updated_at DESC'
end


We can now update our controller code to use our new named_scope

class PendingArticlesController <  ApplicationController
    def index
        @pending_articles = Article.pending
    end


end

This is much better! Now we have a very simple controller action which is easy to read and understand at a glance. We have also moved the find logic into the Article, which is where it belongs.

While this is a very simple example, consider a controller action with many lines and very large find statements. These can become very difficult to understand and hard to maintain.

Hopefully this small tip helps.

Filed under: ruby on rails

andyman says...

I had a great time at the Aloha On Rails conference (Oct 5 and 6), getting to meet other Ruby on Rails developers and listening to the speakers.  It was great being able to see the people behind some of the blogs I read, or gems/plugins that I use.  I really really hope that this becomes an annual event.

Here are the top pieces of takeaway value that I personally got out of the conference from Day 1 (for a description of each session, see Aloha On Rails Sessions). I'll write more on Day 2's sessions in another post.

From Chad Fowler's keynote: Passionate Programmer:
  • A lot of developers hate having to do marketing. (like me) But marketing is a moral imperative. If you believe that you have a great product or that you have a great service to offer that will be of value to others, then you're cheating others if you don't tell them about it.
  • What are you spending your passion on? As passion drains away, execution drains away.
  • The problem with inspiration is that it is not consistent. You need to systematize it.  Calling software development an "art" is just an excuse to not systematize it.
  • The framework for succeeding in the software industry is: choose market, invest, execute, market, systematize
  • Something that I thought was odd was that Chad said that he wouldn't do programming if he didn't get paid for it.  I love to program, and my favorite projects have been the ones I don't get paid for. And there's all the developers who truly enjoy doing open source.  Chad does say to practice though (Code Kata and Ruby Quiz), but I guess he means it with the goal of practicing so that you getting paid more later on.

From Blythe Dunham's session: Hey is that your database crying?
 One group of tips I was reminded of is: While Rails does a good job of doing validations, it is useful and safer to also put some of those validations in the database as well, such as having "not null" columns, using unique keys, and default values right in the migrations.

From Greg Pollack's session: On the Edge of Rails Performance
I pretty much got my full registration cost back from the value of this talk. Greg went over 9 awesome plugins/libraries for rails performance and optimization. They are listed here:
Presentation Notes « Envy Labs

From Marty Haught's session: Lean Teams - How To Do More With Less"
Essentially just stay focused on adding nothing but value, learning from the users, maximize flow/minimize effort, and ship features when ready. Also he introduced me to the "kanban" system which is an agile methodology which seems to increase the flow of value by limiting the number of works in progress. Here's the link for kanban: Limited WIP Society - Home of Kanban for Software Development

Desi McAdam's session: Dragons, Riddles, and Rails Applications
One practice I haven't heard much of but makes a lot of sense is: "Keep explaining to the client what you were doing for the client." This is especially useful when the work doesn't involve changes that are apparent/visible to the client, such as rescuing/refactoring nightmare legacy code so that it can be more maintainable or enhanced.

Pat Maddox's session: Domain Driven Rails
  • A good metric of code quality is WTF's per minute when someone is reading through the code.
  • Check out the resource_controller plugin
  • Sometimes ActiveRecord callbacks (after_create) can make it harder to follow the code.
  • Sometimes moving things from the controller to the model might may testing slow/hard and code hard to follow (ex: an after_create activation/verification email delivery for a User model), in which case a service class would be more appropriate. Look at alternatives to callbacks: service classes, command objects, event handlers
  • Stuff that goes in the <title> tag should really use a yield and content_for, rather than being set in the controller or model, since this really is part of the view.

Yehuda Katz's session: Rails 3 Public API
In Rails 3, some of the big long methods are being broken down into smaller parts, which means it can be more easily customizable. We'll be able to get stripped down "metal" versions of many of some of the fat bloated classes and choose which modules/mixins to put in.

Michael Nieling and atthew McVicar's session: You Don't Need A Logo
  • Details matter, be consistent, design is never done
  • Design and details differentiated Starbucks, iPod, and Flickr from their competitors who had similar producs. They had the best design and looked at all the details of the entire experience.
  • Design stewardship - everyone needs to be involved in complying with the design. Have a Design Usage Guide. An design needs to be at almost every point of the process.
  • When using a design agency, get them to explain/justify every design decision, and provide you with documentation. Have to be able to justify how it is delivering actual value, rather than just based on "taste".
  • Most people can't tell the difference between good and #1 (Chad vs Kelly Slater when surfing), but can tell between a beginner vs good.
  • Get the client to tell the "what" and the "why". We'll figure out the "how".

Panel session: Is Agile Too Slow?
  • Identify your sacred cows and question them (always write tests for everything? etc)
  • Sometimes putting together cucumber scenarios helps out to flesh out requirements. They let you know when you are done.
  • Selenium - lets you test the UI
  • When is hacking (going without tests) OK?  "If you're not getting paid for it", or "at the start" if you don't know if the project/prototype will go forward

Here is part two.

Filed under: Ruby On Rails

speric says...

Filed under: Ruby on Rails

jarin says...

Here are the slides from my Moonshine talk at SD Ruby. I’ll update it with video of the presentation once it goes up on the SD Ruby Podcast.

Filed under: Ruby on Rails

Whilst searching for a gem/plug-in to help with storing encrypted notes in a Rails app, I found strongbox. It uses public key encryption to encrypt and store data on a ActiveRecord attribute - Spike has a great writeup on his blog. One limitation I encountered was that it only uses one key to encrypt the data, which wasn't going to work when I have multiple users, all storing private information.

491113684_ee82e217f1_m.jpg
So I wrote a wrapper around strongbox that I am releasing called Safe - a Rails engine for storing encrypted data. Safe handles the generating of the public and private keys and uses strongbox to encrypt and decrypt the data. It's still in early stages, and it doesn't support all of the options that strongbox does, but it is on the TODO list.

So let me know if you find it useful and don't forget to symlink the keys directory in your deployment scripts!


Bit Zesty - Ruby on Rails developers in London.
 

Filed under: ruby on rails