All I Post These Days Is Status Updates

Here’s where we are at the moment.

Master Space & Time With JavaScript: Ember

I think I may have finally gotten my head around the Ember release plans. My current understanding is that:

  • A 1.0 final release of core ember is imminent, possibly as soon as September 1.
  • There’s another major overhaul of Ember-data (the “jj-abrams” reboot branch), which will become the master branch sometime between now and the 35th of Octvember. In other words, who knows?

Which leaves me with the following plan:

  1. Once Ember 1.0 is released, I’ll start on a relatively minor revision of the book that will make sure it works with 1.0, allude to some new features, maybe talk about the Ember Inspector if I get ambitious.
  2. I actually don’t plan to add all that much new content, it’s already 108 pages, I doubt it will go above 130. (For reference, the

    Continue reading “All I Post These Days Is Status Updates”

All I Post These Days Is Status Updates

Here’s where we are at the moment.

Master Space & Time With JavaScript: Ember

I think I may have finally gotten my head around the Ember release plans. My current understanding is that:

  • A 1.0 final release of core ember is imminent, possibly as soon as September 1.
  • There’s another major overhaul of Ember-data (the “jj-abrams” reboot branch), which will become the master branch sometime between now and the 35th of Octvember. In other words, who knows?

Which leaves me with the following plan:

  1. Once Ember 1.0 is released, I’ll start on a relatively minor revision of the book that will make sure it works with 1.0, allude to some new features, maybe talk about the Ember Inspector if I get ambitious.
  2. I actually don’t plan to add all that much new content, it’s already 108 pages, I doubt it will go above 130. (For reference, the Backbone book is 120, with longer code samples). I want to go through an authentication example. I may talk about components or more advanced view topics.
  3. Some of that is just going to wait until Ember-data gets sorted out, so I’m not rewriting the thing over and over.
  4. The 1.0-related release may be the one that triggers the price increase (based on length). We’ll see. But it’s coming.

You can buy Master Space and Time with JavaScript.

Trust-Driven Development

Work is proceeding on this a little faster. I think I have about 30 pages of text (it’s a little hard to tell because I have a lot of blank chapters adding pages).

I like what I have, but the organization is going to need work. Right now it’s really a set of interconnected essays about project topics (already written topics include points and velocity, user stories, iteration management, the introduction, and a couple of other topics.

The current plan is to start releasing actual text around WindyCityRails, September 12th. That triggers the price increase from $15 to $20, but I’ll probably soften the blow with a promotion over WindyCityRails.

If it’s not ready then, plan B is the same thing but over Ruby DCamp two weeks later.

You can buy Trust-Driven Development.

And another thing…

Weird as it may sound, this represents me trying to clear the decks because a new project has come up. It’s not official yet, and it’ll get its own blog post when it is.

Web Development with Clojure; Processing Big Data with MapReduce screencast

Web Development with Clojure now in beta; Processing Big Data with MapReduce screencast now available

Heroku Postgres at Postgres Open and PostgreSQL Conf EU

The Heroku Postgres team is hitting the road in coming months and we’d love to connect with you. If you’d like to meet up with us at any of the events below, drop us a line or Tweet us @HerokuPostgres.

The first opportunity to connect with us is in September at Postgres Open. If you’ve already got your tickets for Postgres Open, join us for drinks and/or pizza at Clark Ale House on Tuesday, September 17, and make sure to check out talks by Craig Kerstiens and Peter Geoghegan.

If you don’t already have your ticket for Postgres Open, but are interested in going, we’ve got a chance for you to win a ticket from us for free.

Win A Ticket to Postgres Open

We’re giving away 3 tickets to PG Open. For your chance to win a ticket, we want to see the creative ways you’re using dataclips with your Heroku Postgres database. Submissions can be a really impressive query or a great integration. The key to either is that it should be empowering you to better run your business with data. To enter:

1. Create your dataclip or integration
2. Submit the following to postgres@heroku.com:

  • Your name
  • Your role
  • Your organization and what the company does
  • A link to the dataclip or integration you’ve built

We will be announcing winners on August 29, 2013. The winners will be chosen at the sole discretion of the Heroku Postgres team.

PostgreSQL Conf EU

Those of you in Europe will have an opportunity to connect with the team as well. A large part of the team will be at PG Conf EU. Make sure to attend talks by four of our team members:

Conclusion

If you’re going to be at either of the above conferences, we’d love to talk to you. However, you don’t have to wait. If you ever have operational issues with your database, you can find help at help.heroku.com, or for product related questions and feedback you can contact us at postgres@heroku.com.

Cross-posted from the Heroku Postgres blog, where you can keep up with the latest Heroku Postgres news.

Dragonfly on Heroku – The difference between the request time and the current time is too large

Lately we have been experiencing intermittent exceptions on Heroku when uploading images to S3 using “Dragonfly” on Heroku:

1
Excon::Errors::Forbidden: Expected(200) <=> Actual(403 Forbidden)

It seems that this exceptions doesn’t happen on every upload – so while examining the response body from S3 – we got this:

1
<Excon::Response:0x000000062a09d0 @body="<?xml version="1.0" encoding="UTF-8"?>n<Error><Code>RequestTimeTooSkewed</Code><Message>The difference between the request time and the current time is too large.</Message><MaxAllowedSkewMilliseconds>900000</MaxAllowedSkewMilliseconds><RequestId>B9CB09E0E0A7054B</RequestId><HostId>K3liRup7BjJoxBXgkCGpD7NSk/0jIUy6+nBY5Y63akNx4MNNLMvj7zSlEadDn87Q</HostId><RequestTime>Mon, 26 Aug 2013 11:39:58 +0000</RequestTime><ServerTime>2013-08-26T11:55:29Z</ServerTime></Error>", @headers={"x-amz-request-id"=>"xxxx", "x-amz-id-2"=>"xxxx", "Content-Type"=>"application/xml", "Transfer-Encoding"=>"chunked", "Date"=>"Mon, 26 Aug 2013 11:55:28 GMT", "nnCoection"=>"close", "Server"=>"AmazonS3"}, @status=403>

and especially this:

1
<Message>The difference between the request time and the current time is too large.</Message>

After investigating Continue reading “Dragonfly on Heroku – The difference between the request time and the current time is too large”

Dragonfly on Heroku – The difference between the request time and the current time is too large

Lately we have been experiencing intermittent exceptions on Heroku when uploading images to S3 using “Dragonfly” on Heroku:

1
Excon::Errors::Forbidden: Expected(200) <=> Actual(403 Forbidden)

It seems that this exceptions doesn’t happen on every upload – so while examining the response body from S3 – we got this:

1
<Excon::Response:0x000000062a09d0 @body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>RequestTimeTooSkewed</Code><Message>The difference between the request time and the current time is too large.</Message><MaxAllowedSkewMilliseconds>900000</MaxAllowedSkewMilliseconds><RequestId>B9CB09E0E0A7054B</RequestId><HostId>K3liRup7BjJoxBXgkCGpD7NSk/0jIUy6+nBY5Y63akNx4MNNLMvj7zSlEadDn87Q</HostId><RequestTime>Mon, 26 Aug 2013 11:39:58 +0000</RequestTime><ServerTime>2013-08-26T11:55:29Z</ServerTime></Error>", @headers={"x-amz-request-id"=>"xxxx", "x-amz-id-2"=>"xxxx", "Content-Type"=>"application/xml", "Transfer-Encoding"=>"chunked", "Date"=>"Mon, 26 Aug 2013 11:55:28 GMT", "nnCoection"=>"close", "Server"=>"AmazonS3"}, @status=403>

and especially this:

1
<Message>The difference between the request time and the current time is too large.</Message>

After investigating a bit, we found that it means that our requests to S3 are timestamped and compared to the server local time in order to assure authenticity,
so it seems that something went wrong with our local clock on Heroku.
After realizing that the local time on the heroku machines (using the rails console) was correct, we monkeypatched the Dragonfly::DataStorage::S3DataStore module to use the sync_clock method on every access to the storage getter.

config/initializers/sync_dragonfly.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Dragonfly::DataStorage::S3DataStore.module_eval do

  def storage
    require 'fog'

    @storage ||= Fog::Storage.new(
        :provider => 'AWS',
        :aws_access_key_id => access_key_id,
        :aws_secret_access_key => secret_access_key,
        :region => region
    )
    @storage.sync_clock
    @storage
  end
end

What this patch does is simply to sync the clock before returning the storage object.

Currently, one day after we seem to have no exceptions of this kind anymore.

Dragonfly on Heroku – The difference between the request time and the current time is too large

Lately we have been experiencing intermittent exceptions on Heroku when uploading images to S3 using “Dragonfly” on Heroku:

1
Excon::Errors::Forbidden: Expected(200) <=> Actual(403 Forbidden)

It seems that this exceptions doesn’t happen on every upload – so while examining the response body from S3 – we got this:

1
<Excon::Response:0x000000062a09d0 @body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>RequestTimeTooSkewed</Code><Message>The difference between the request time and the current time is too large.</Message><MaxAllowedSkewMilliseconds>900000</MaxAllowedSkewMilliseconds><RequestId>B9CB09E0E0A7054B</RequestId><HostId>K3liRup7BjJoxBXgkCGpD7NSk/0jIUy6+nBY5Y63akNx4MNNLMvj7zSlEadDn87Q</HostId><RequestTime>Mon, 26 Aug 2013 11:39:58 +0000</RequestTime><ServerTime>2013-08-26T11:55:29Z</ServerTime></Error>", @headers={"x-amz-request-id"=>"xxxx", "x-amz-id-2"=>"xxxx", "Content-Type"=>"application/xml", "Transfer-Encoding"=>"chunked", "Date"=>"Mon, 26 Aug 2013 11:55:28 GMT", "nnCoection"=>"close", "Server"=>"AmazonS3"}, @status=403>

and especially this:

1
<Message>The difference between the request time and the current time is too large.</Message>

After investigating a bit, we found that it means that our requests to S3 are timestamped and compared to the server local time in order to assure authenticity,
so it seems that something went wrong with our local clock on Heroku.
After realizing that the local time on the heroku machines (using the rails console) was correct, we monkeypatched the Dragonfly::DataStorage::S3DataStore module to use the sync_clock method on every access to the storage getter.

config/initializers/sync_dragonfly.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Dragonfly::DataStorage::S3DataStore.module_eval do

  def storage
    require 'fog'

    @storage ||= Fog::Storage.new(
        :provider => 'AWS',
        :aws_access_key_id => access_key_id,
        :aws_secret_access_key => secret_access_key,
        :region => region
    )
    @storage.sync_clock
    @storage
  end
end

What this patch does is simply to sync the clock before returning the storage object.

Currently, one day after we seem to have no exceptions of this kind anymore.

The Heroku Security Researcher Hall of Fame

Starting today, Heroku would like to publicly thank all the independent security researchers who have practiced responsible disclosure and helped us remediate issues.

The Heroku Security Researcher Hall of Fame lists these researchers, along with the date of their initial report. If you've found a new security issue on our platform, we'd love to hear from you.

Our intent is for this list to be comprehensive, going back to our beginning. If you’ve reported a vulnerability to us in the past, and you’re either not listed or you’d like your listing changed (e.g., typos, change a link) or removed entirely, just let us know.

Ground Rules:

  • Customer applications are ineligible for multiple reasons. Very roughly, this means we don’t list reports for *.herokuapp.com, and aspiring researchers should look at *.heroku.com. This isn’t an absolute rule, however. Older customer applications (i.e., our deprecated “Bamboo” stack) are hosted in *.heroku.com. If you do find a security vulnerability in another customer’s application, please do still let us know. We’re happy to forward the report to the customer either with or without your contact information.

  • Only one listing per vulnerability. For duplicate reports, the first reporter wins. If necessary, we’ll check the timestamps.

  • Only one listing per reporter. For researchers kind enough to report multiple issues, we’re still figuring out how best to honor their contributions.

  • Heroku and Salesforce employees will not be listed in the Hall of Fame.

  • The decision to list a researcher in the Hall of Fame is made at the sole discretion of the Heroku Security Team.

  • We don’t offer cash rewards, but we can link to your personal or professional site, and we’ll mail you a stylish Heroku t-shirt.

Again, thank you for helping make the world safer.

-Tom Maher
Heroku Security Team

New PageSeven Web Frameworks in Seven Weeks: Adventures in Better Web Apps now in beta

Seven Web Frameworks in Seven Weeks: Adventures in Better Web Apps now in beta

Building Twelve Factor Apps on Heroku

At Heroku, we’ve had the privilege of running and managing millions of amazing apps built by our users. Over a year ago, Heroku co-founder Adam Wiggins published the Twelve Factor App, based directly on these experiences. It distills best practices for building modern cloud applications into a 12-factor methodology specifically designed to maximize developer productivity and application maintainability.

Twelve Factor apps are built for agility and rapid deployment, enabling continuous delivery and reducing the time and cost for new developers to join a project. At the same time, they are architected to exploit the principles of modern cloud platforms while permitting maximum portability between them. Finally, they can scale up without significant changes to tooling, architecture or development practices. Because the Twelve Factor methodology is a core part of how successful apps are built on Heroku, it is now documented in our Dev Center.

In this post, we review the aspects of Heroku that help you build apps based on these tenets. For instance, decomposing your app into a set of lightweight processes is a prerequisite for running on Heroku and is the embodiment of the Twelve Factor principle of executing the app "as one or more stateless processes". However, there are several other, subtler, factors that should also be considered when deploying to Heroku, or any modern distributed environment. For those not familiar with the original Twelve Factors, we'll summarize them here. For developers that are already familiar with the Twelve Factor methodology, we'll re-introduce them in the specific context of building and deploying to Heroku.

During development

Applications should be thought of as self-contained, self-describing and independent entities. In practice this means each application should declaratively define all dependencies without any reliance on existing system packages. Nor should it embed the location of any external dependencies in the app source, instead relying on such configuration to be specified in the runtime environment.

Developers will immediately recognize their buildpack’s use of language-specific tools, such as Ruby's Bundler and Clojure's Leiningen, as providing the necessary level of dependency declaration and isolation here, and will be familiar with Heroku's heroku config:set CLI command used to update external dependencies without modifying the app's source code.

Using modern language toolchains alongside the strict separation of code and config that the Heroku CLI and Add-ons program require ensures a portable application and provides a set of environment-independent practices that enable you to run in the same fashion locally as your app does in production.

At runtime

Apps on Heroku are subject to several runtime parameters that ensure the app can be efficiently run in a distributed environment and is resilient to adverse conditions. These are in-product manifestations of several best-practices in application operation.

Consider the ephemeral filesystem which ensures a stateless runtime, or the fast process startup/shutdown requirements which result in an application whose runtime distribution can be quickly adjusted in response to underlying system deviations.

One of the most visible and fundamental concepts of Heroku is that of the process model. By running your application as one or more lightweight processes, and not a monolithic executable, you can more granularly scale the app to match a diverse workload — a sort of in-app horizontal scaling.

The Procfile, your app’s process manifest, informs the runtime of your app’s unique composition and tools like Foreman (locally) and the Heroku dyno manager (remotely on Heroku) manage its execution.

When managing

Beyond the automated runtime service provided by the Heroku platform, it must also be possible to execute user-initiated tasks against the app as well as see the app's runtime log output. In compliant applications, these management and visibility requirements are well supported on Heroku.

To execute a one-off task, such as a database migration or arbitrary command via REPL, simply provision a one-off dyno. To see your app's log output, configure your app to log to stdout and its real-time log stream, aggregated across the distributed Heroku runtime, will be available via the CLI with heroku logs -t or in one of the many logging add-ons.

Conclusion

Heroku is not only a platform; it is also a set of practices that embody the right way to develop modern applications. Understanding and applying these practices when developing your app ensures the most resilient and performant experience on Heroku.

StatusPage Add-On in Public Beta

Sharing your app’s status is critical for communicating and building trust with your users – whether it’s down for maintenance, experiencing problems with service providers, suffering from interruptions or performance problems, or up and running perfectly. Here at Heroku, we accomplish this with Heroku Status. But today, we’re introducing our first add-on that makes it easy to communicate app status with users of your app – StatusPage, now in public beta.

StatusPage lets you build your own branded status page so you can share status information and public metrics about your app while also providing highly-available downtime communication. Enable the Heroku integration by setting a few environment variables in your app that will extend the error and maintenance pages Heroku serves automatically in the event your app encounters system-level errors or enters maintenance mode.

StatusPage lets you present three major categories of status information in a branded experience. First, communicate the overall status of your platform, such as “All Systems Operational”, as well as the status of individual components and services:

StatusPage

Then, communicate public metrics about your service, such as API uptime, error rate, or user activity. This communicates important data to existing users while also building trust with prospects. Metric data can be pulled from Librato, New Relic, TempoDB, Pingdom, and Datadog. Users of the New Relic, Librato, or TempoDB Heroku add-ons can integrate immediately – just paste a few API keys and you’re ready to go.

StatusPage

Finally, display a running log of incidents for historical visibility.

StatusPage

For notifications during critical incidents, events and outages, customers can subscribe via email, RSS, SMS, or webhooks, ensuring they’re informed when it matters most.

Just run heroku addons:add statuspage to get the add-on. It's in public beta, which means it is available for use to any Heroku user, but some changes may be made before it goes into GA. While in public beta, StatusPage is free to get started with. Find out more about using it in our Dev Center.

Want to try more add-ons? The Heroku Add-Ons Marketplace makes it easy to add technologies you love to your Heroku app. We have add-ons for logging, caching, persistence and many other categories, all available as fully-managed services that you can add and scale in a single command.

Test iOS Apps with UI Automation now in print; New Magazine

Test iOS Apps with UI Automation now in print; New Magazine

A “Free” online course on Sinatra

A “Free” online course on Sinatra

RubyLearning announces the eleventh batch of its “Free” online “Sinatra” course starting from Saturday 7th Sept. 2013.

Sinatra – quickly create tiny web apps and services

Is the course really free?

A lot of effort and time goes into building such a course and we would really love that you pay at least US$ 15 for the course. Since this is a “Pay if you Like” course, you are under no obligation to pay and hence the course would be free for you.

For those who contribute US$ 15, we shall email them a copy of the book (.pdf) “Introduction to Sinatra” – the course is based on this book.

How do I register and pay the course fees?

  • First, create an account on the site and then pay the fees of US$ 15 by clicking on the PayPal button Paypal
  • After payment of the fees please send us your name to satish [at] rubylearning [dot] org so that we can send you the eBook, which normally takes place within 48 hours.
  • If you want to take the course for free, please just create an account and send us your name (as mentioned above).

Who’s It For?

Anyone who knows the Ruby programming language can take the “Sinatra” course, and is a starting point for people new to Sinatra and a guide to help learn it as quickly and easily as possible.

Dates

The course starts on Saturday 7th Sept. 2013 and runs for a week.

What’s Sinatra?

Sinatra is a micro-framework for quickly creating tiny web-applications and small services in Ruby. It is not a Model-View-Controller (MVC) based framework.

Please read – Sinatra, a Ruby web framework, and Why it Matters.

Heroku Logo

Thanks to Heroku for providing the facility to create free hosting accounts for all the participants, to host their apps created during the course. Heroku – it’s fast, it’s easy, and it just works!

What Will I Learn?

In this introductory course, you will learn the essential features of Sinatra that you will end up using every day. The course topics are:

  • What is Sinatra?
  • Sinatra Installation and its dependencies
  • Routes
  • set
  • before block
  • pass
  • status
  • Building a trivial Sinatra application
  • Deployment of a Sinatra app to Heroku
  • Views – ERB and HAML
  • Handler
  • Form parameters
  • Layouts
  • Error Handling – 404 and 500
  • Helpers
  • Exercises
    • Hosting a static webpage on Heroku
    • Text String Reversal Service
    • Stock Exchange Quote Service
    • Using Sinatra to access the Google+ API
    • Running a Sinatra app using JRuby
    • A Sorter Web Service in Sinatra
    • Finding Photos on Flickr
    • A Sinatra app to access GEO Info via GeoCoder
    • Sinatra Street View
    • Simple CRUD app with ActiveRecord, SQLite3 and YAML
  • Using Rack Middleware

You can read through the RubyLearning FAQ.

Some Fun Apps

Sinatra Icon

Here are some of the fun apps created by the previous batch participants and deployed to Heroku:

Yes, you too can build all such applications and many more.

Famous Rubyists using Sinatra talked to RubyLearning and gave us their views on:

Also, thanks to Adam Keys, Aaron Quint, and Ryan Tomayko for sharing their expertise on Sinatra with the course participants.

So hurry, registrations have started.

By the end of the course, you can quickly create your own tiny web-applications in Ruby and write lots of small services.

Technorati Tags: , , , , ,


(Powered by LaunchBit)

Sinatra: Some Questions from Ruby Newbies

Darren Jones in his excellent book Jump Start Sinatra says “Since its release in 2007, Sinatra has quickly gained in popularity in the Ruby web community due to its elegant simplicity and classy syntax. Everybody who uses it falls in love with its elegant simplicity and classy syntax.”

RubyLearning will be conducting a “free” (i.e. pay if you like) online course on Sinatra from 7th Sept. 2013 and many of the would-be participants (mostly Ruby newbies) would have a plethora of questions related to Sinatra.

Satish Talim of RubyLearning.org talked to Ruby Gurus Andy Lindeman, Carlo Pecchia, Dan Mayer, Darren Jones, Nathan Esquenazi and Sudarshan Shubakar to answer some of the would-be participant’s questions.


Satish>> A warm welcome to you all. For the benefit of the would-be Sinatra course participants, could each one of you tell us something about your self?

Andy LindemanAndy>> I am a software generalist focused on web and mobile. I like open source and work primarily on RSpec. I work at Big Nerd Ranch, primarily writing web application backends in Ruby and Rails. I dabble a good bit: currently Objective C/iOS, Clojure, Erlang, and client-side JavaScript frameworks are on my radar. I like working on open source and meeting new folks in the community.

Carlo PecchiaCarlo>> I am an IT engineer mainly interested on agile methodologies and “good practices” for developing large and complex systems. I am also interested in web architectures and emerging programming languages.

Dan MayerDan>> I am a tech lead on the LivingSocial consumer web team. I have been developing Ruby applications since 2007 and often work with both Rails and Sinatra. I believe in trying to keep code small, and breaking applications up into logical components and services. My thoughts on development can be found on http://mayerdan.com. I am on twitter as @danmayer

Darren JonesDarren>> I am the author of Jump Start Sinatra, a short book that helps you to get up to speed with Sinatra over a weekend, published by Sitepoint. I have been using Sinatra since 2009 and used it to build the Cards in the Cloud website. I live in Manchester in the UK where I teach Mathematics and enjoy playing water polo.

Nathan EsquenaziNathan>> I am one of the creators of the Padrino framework, enabling powerful extensions to the Sinatra core and the co-founder of CodePath, providing practical training to engineers interested in learning mobile development.

Sudarshan ShubakarSudarshan>> I am a software developer based out of Pune, India. I enjoy working with design principles and patterns, learning new programming languages and a bit of open source development. I am majorly a Java developer for the past 11 years and have recently started working on Ruby out of interest.

Satish>> What is Sinatra best suited for?

Andy>> Simple web apps, especially those that are mostly APIs or only have a few views.

Carlo>> Sinatra is an “essential” framework for Ruby based web application. Talking about “web app” the point of reference is – without any doubt – RubyOnRails (RoR): Sinatra is lightweight compared to it. You have less features, but also less stuff to digest to start with. Personally I’ve used Sinatra (and I was really satisfied by it) for apps where data complexity and user interactions are not critical points (in my case: internal enterprise app).

Dan>> Sinatra is great for smaller applications and apis. Sinatra fits really well when there is a limited front end which uses a lot less of the standard view layer helpers and other features common in Rails. I have personally found that Sinatra is best for APIs and micro sites. If an application with a significant front end is going to be developed, it is often best to start with rails as you will start to home grow and try to replace many common features of rails with your own bad implementations. Finally people often forget how much rails helps in terms of basic security precautions, making it harder to make common mistakes. There is a well known Ruby community quote that I can’t find attribution for, “every Ruby web framework eventually becomes a horrible bad and buggy implementation of rails”.

Darren>> Putting your Ruby code onto the web! At its heart Sinatra is essentially just a wrapper for making it easy to deal with HTTP requests and responses by providing some very nice helper methods. This means that it is suited for anything that you can write in Ruby. It can handle small projects brilliantly but is also great for larger projects too.

Nathan>> Sinatra is incredibly well-suited for building REST APIs for mobile clients as well as web back-end services that are paired with modern javascript frameworks like Backbone, AngularJS, Ember, et al.

Sudarshan>> The Sinatra book introduction says it best by these statements:
* In Sinatra, you can write short ad hoc applications or mature, larger application with the same easiness.
* Sinatra really shines when used for experiments and application mock-ups or for creating a quick interface for your code.
My take on this is that Sinatra gets you started quickly on whatever problem you are trying to solve (with a web/URL based solution) quickly. There is hardly a learning curve and you can have a meaningful implementation of your solution within no time.

Another point where Sinatra is most useful is when you would like finer control over how your application is organized. This discussion on stackoverflow.com provides some good inputs on how Sinatra compares to Rails. As one person says in this discussion, there is no limit to what you can do with it.

Satish>> I am a Ruby newbie and if I learn Sinatra, does that help me with Ruby on Rails?

Andy>> I think it depends on exactly how much you know.

For folks with little background on programming or web application development at all, I think it’s a great fit. There’s not very much “magic” and it’s easy to get up and running quickly.

Carlo>> Sure! Learning Sinatra gives you all the details about how HTTP protocol is handled; how routing works; how to manage your models; how to talk with a Data Base (noSQL are welcome too); how a template system has to be used; and so on. My suggestion is: start with Sinatra, and *then* consider RoR for “not small” projects.

Dan>> Learning Sinatra is a great way to begin to learn Rails. It will definitely help you learn Rails as it helps you learn Ruby basics as well as common Ruby web development practices. In many ways it is a smaller and simpler way to learn to work with a web framework, which is excellent. I find while this is great for learning, it leads to a less natural project structure and uncommon patterns for larger applications. Actually learning some of the basic web development concepts first in Sinatra would help one to understand why these concepts exist and why they are bit more complicated in Rails.

Darren>> A little, but it is more useful for improving your Ruby. I think that it would help you understand some of the ‘magic’ that Rails does in the background as you have a lot more control with Sinatra.

Nathan>> Sinatra is an excellent introduction to the Ruby language and to web development. Sinatra has a remarkably short learning curve and as such allows for new developers to tinkering with web apps of all sorts with minimal overhead or confusion. The distinct advantage of learning Sinatra while you are developing your Ruby acumen is that Sinatra is very explicit and simple allowing the expressiveness of Ruby itself to shine through.

Sudarshan>> Hmm, will Sinatra help one learn Ruby on Rails… probably not in an obvious manner. However my understanding is that if one tries to build a well-structured MVC application with Sinatra, one would find it easier to appreciate what Rails offers out of the box and why it mandates what it does.

With Sinatra there is almost no mandate apart from the dsl syntax itself. So you are free to organize your application any way you like.

If you are trying to learn Rails while you are developing your pet application, my understanding is that you may find it slightly difficult because you may need to deviate from your problem domain to understand the framework. This probably isn’t true if you are just trying to learn Rails with just a mock application.

With Sinatra, like I’ve already mentioned, there is hardly a learning curve and you stay focused on your problem domain.

Satish>> How much Ruby do I have to cover in order to start learning Sinatra?

Andy>> I think it again depends on what an individual developer’s background is.

Developers who are new to Ruby but know other object-oriented languages will likely pick up enough Ruby to be proficient very quickly.

Other developers may need more basics about the structure and basic syntax and semantics of programming languages first.

That said, I think you could pair a lot of the learning: while introducing a Sinatra concept, also introduce some Ruby concepts.

Carlo>> At the very beginning “not too much”, but if and when you want to code seriously you have to dirty your hands. There is no escape! :-)

Dan>> I would make sure to cover some Ruby basics firsts:

* Running a ruby script
* variables
* method calls
* basic data structures (array, hashes, strings, and numericals)

After making sure those basics are understood, I think you could get into Sinatra specifics. It would also likely help to have a basic knowledge of html, CSS, and possibly JSON, if you are planning to cover api endpoints.

Darren>> Not much at all to get started. But the more Ruby you know, the better your Sinatra applications will be. As I mentioned in my answer to question 1, Sinatra apps are basically just Ruby apps put on the web, so the standard of your Sinatra app will be directly linked to how much Ruby you know. The Sinatra source code is written in Ruby and a great exercise is to read through it (it’s only around 2000 lines and very well commented). This will help to improve your Ruby skills and help you to understand how Sinatra works.

Nathan>> Sinatra is entirely built using idiomatic ruby constructs and patterns. That said you can start tinkering with Sinatra well before you have a strong grasp on Ruby. I would recommend taking the time to first familiarize yourself with the basic ruby constructs and then you can quickly dive in and learn by doing.

Sudarshan>> Have you seen http://www.sinatrarb.com/ !!:)

I needed a beginner’s level knowledge of Ruby to start using Sinatra.

However, when you are learning a new language like Ruby and using something like Sinatra to do so, it is important to understand where the domain of the framework starts blurring and your problem domain begins to shine.

So you may need to understand Ruby much deeper to efficiently solve the actual problem that you are working on.

Satish>> How important is it for me to know Rack while learning Sinatra?

Andy>> I think Rack is pretty simple for experienced developers to understand, but understanding why it’s needed and how it fits is a bit more abstract and difficult. I don’t think new developers need to understand Rack while learning Sinatra.

Carlo>> Rack is a very basic and important component, don’t be afraid by it. I strongly encourage you to take half a day to study it: it’s time well invested.

Dan>> While Rack is great, I think it could likely be skipped over at the beginning to allow new users to just think in terms of a Sinatra request and response cycle. It might be a good thing to cover a bit further into the lessons, but to help users get to the first goal to dynamically add information to a page, I don’t believe knowledge of Rack is really necessary.

Darren>> I don’t think you need to know much about Rack, except that Sinatra (and most other Ruby frameworks) uses it extensively in the background. Once you get more confident with Sinatra then you can start to dig a bit deeper into how Rack runs the show in the background, but it isn’t essential when you first start.

Nathan>> Rack is the web-server interface that underlies web development in Ruby. Learning about Rack and Rack middleware development will give the developer an insightful look under the hood at how the request/response model of the web interacts in ruby-based web libraries.

Sudarshan>> It is possible to write simple Sinatra apps in the classic style without using Rack. However as your app begins to gather a bit of complexity, you will want to shift to the Modular style. Here’s where Rack will help you organize your app better. This is of course apart from the benefit of web server abstraction Rack inherently provides.

Satish>> While developing Sinatra apps which style (Modular or Classic) should I use?

Andy>> If the audience is beginners, I’d start with classic because you have to keep very little context in your head. As the audience becomes more experienced, move toward a more modular approach.

Carlo>> It depends roughly on your application “size”. Modular style gives you more maintainable and readable code. Anyway start with Classic and then when your app grows up, consider switching to Modular style.

Dan>> I think for teaching beginners, the Classic style is simpler to understand and would be quicker to get students to the learn / reward cycle. Sinatra apps that grow large, is where the modular approach has many advantages. For larger apis, the modular approach is definitely the way to go, but often I find when you are really utilizing that approach it would make sense to just have a full Rails app. I haven’t ended up building out to many very large Sinatra applications so there might be other advice on this point.

Darren>> It doesn’t matter at all. I really like the fact that the Classic style allows you to get started really quickly and build apps with all the code in just a single file. The modular style makes it easier to organize large applications and is a good approach if you are working in teams as each module can be developed independently of the other. Modular apps also make it easier to reuse and share code in other projects.

Nathan>> While tinkering around learning Sinatra or for extremely simple apps, use classic. For writing middle-wares and production applications, I recommend using Modular. Modular is more explicit and I prefer having my Sinatra apps contained within an explicit class of my choosing. I don’t see many benefits to using the classic style.

Sudarshan>> When you are starting to learn Sinatra, I would recommend using the classic style to get a feel of how things work. If you are building a meaningful application of even moderate complexity, the Modular style will help you keep your code organized. Once you are familiar with the Modular style of organizing your Sinatra app, you may be able to work with the Modular style with ease from the word go.

Well, we have set the ball rolling. What’s your take on this? Kindly post your thoughts as comments to this blog post. Looking forward to some interesting read.

Technorati Tags: , , , , , , ,


(Powered by LaunchBit)

rails validates :presence of boolean – not what you think

Rails validates :presence and boolean fields

First, take a look at this following model:

survey_question.rb
1
2
3
4
5
6
7
8
9
10
11
class SurveyQuestion < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
  has_many :dependent_questions, :class_name => "SurveyQuestion", :as => :owner
  has_many :survey_answers
  serialize :options, Hash

  attr_accessible :owner, :owner_id, :owner_type, :question_body, :question_type, :options, :required, :parent_answer_condition, :client_integration_param_name

  validates :required, :question_type, :question_body, presence: true

end

and a short run in the rails console:

Rails console
1
2
3
4
5
6
7
8
9
10
[3] pry(main)> SurveyQuestion.create!({owner_type: "Survey", owner_id: 1, required: false, question_body: "How old are you?", question_type: "text"})
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Required can Continue reading "rails validates :presence of boolean – not what you think"

rails validates :presence of boolean – not what you think

Rails validates :presence and boolean fields

First, take a look at this following model:

survey_question.rb
1
2
3
4
5
6
7
8
9
10
11
class SurveyQuestion < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
  has_many :dependent_questions, :class_name => "SurveyQuestion", :as => :owner
  has_many :survey_answers
  serialize :options, Hash

  attr_accessible :owner, :owner_id, :owner_type, :question_body, :question_type, :options, :required, :parent_answer_condition, :client_integration_param_name

  validates :required, :question_type, :question_body, presence: true

end

and a short run in the rails console:

Rails console
1
2
3
4
5
6
7
8
9
10
[3] pry(main)> SurveyQuestion.create!({owner_type: "Survey", owner_id: 1, required: false, question_body: "How old are you?", question_type: "text"})
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Required can't be blank
from /Users/eladmeidar/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-4.0.0/lib/active_record/validations.rb:57:in `save!'
[4] pry(main)> SurveyQuestion.create!({owner_type: "Survey", owner_id: 1, required: true, question_body: "How old are you?", question_type: "text"})
   (0.1ms)  begin transaction
  SQL (6.6ms)  INSERT INTO "survey_questions" ("options", "owner_id", "owner_type", "question_body", "question_type", "required") VALUES (?, ?, ?, ?, ?, ?)  [["options", "--- {}\n"], ["owner_id", 1], ["owner_type", "Survey"], ["question_body", "How old are you?"], ["question_type", "text"], ["required", true]]
   (2.3ms)  commit transaction
=> #<SurveyQuestion id: 1, owner_id: 1, owner_type: "Survey", question_body: "How old are you?", question_type: "text", options: {}, required: true, parent_answer_condition: nil, client_integration_param_name: nil>

Note that SurveyQuestion has a boolean attribute named required, we also added it to a :presence validation along side other attributes.
When we tried to create an instance of SurveyQuestion in the console with a required: false value, we got the following exception

1
ActiveRecord::RecordInvalid: Validation failed: Required can't be blank

Obviously, it is there. what happened?

ActiveModel::Validations::PresenceValidator

ActiveModel::Validations::PresenceValidator is the class responsible to handle :presence validations in ActiveModel, there it is:

rails/activemodel/lib/active_model/validations/presence.rb
1
2
3
4
5
class PresenceValidator < EachValidator # :nodoc:
  def validate_each(record, attr_name, value)
    record.errors.add(attr_name, :blank, options) if value.blank?
  end
end

The PresenceValidator basically adds an error when the value of the validated field returns true for #blank? but, the way Object#blank? treats booleans is the way that causes this issue:

Object#blank?
1
2
[1] pry(main)> false.blank?
=> true

Which means, that this is the reason why the :presence validation is failing for boolean fields with a false value, it simply returns true for false values.

Solution

Not really a solution, rather an ugly workaround but the way to get it done is to use the :inclusion validation instead.

survey_question.rb
1
2
3
4
5
6
7
8
9
10
11
class SurveyQuestion < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
  has_many :dependent_questions, :class_name => "SurveyQuestion", :as => :owner
  has_many :survey_answers
  serialize :options, Hash

  attr_accessible :owner, :owner_id, :owner_type, :question_body, :question_type, :options, :required, :parent_answer_condition, :client_integration_param_name

  validates :question_type, :question_body, presence: true
  validates :required, inclusion: [true, false]
end

I think that a better solution for this problem is to pass the column/field object to the validation as well. It will allow any validator such as PresenceValidator to perform specific validation techniques that match the field/column type – in this case – allowing a boolean field to have a false value.

rails validates :presence of boolean – not what you think

Rails validates :presence and boolean fields

First, take a look at this following model:

survey_question.rb
1
2
3
4
5
6
7
8
9
10
11
class SurveyQuestion < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
  has_many :dependent_questions, :class_name => "SurveyQuestion", :as => :owner
  has_many :survey_answers
  serialize :options, Hash

  attr_accessible :owner, :owner_id, :owner_type, :question_body, :question_type, :options, :required, :parent_answer_condition, :client_integration_param_name

  validates :required, :question_type, :question_body, presence: true

end

and a short run in the rails console:

Rails console
1
2
3
4
5
6
7
8
9
10
[3] pry(main)> SurveyQuestion.create!({owner_type: "Survey", owner_id: 1, required: false, question_body: "How old are you?", question_type: "text"})
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: Required can't be blank
from /Users/eladmeidar/.rvm/gems/ruby-1.9.3-p448/gems/activerecord-4.0.0/lib/active_record/validations.rb:57:in `save!'
[4] pry(main)> SurveyQuestion.create!({owner_type: "Survey", owner_id: 1, required: true, question_body: "How old are you?", question_type: "text"})
   (0.1ms)  begin transaction
  SQL (6.6ms)  INSERT INTO "survey_questions" ("options", "owner_id", "owner_type", "question_body", "question_type", "required") VALUES (?, ?, ?, ?, ?, ?)  [["options", "--- {}\n"], ["owner_id", 1], ["owner_type", "Survey"], ["question_body", "How old are you?"], ["question_type", "text"], ["required", true]]
   (2.3ms)  commit transaction
=> #<SurveyQuestion id: 1, owner_id: 1, owner_type: "Survey", question_body: "How old are you?", question_type: "text", options: {}, required: true, parent_answer_condition: nil, client_integration_param_name: nil>

Note that SurveyQuestion has a boolean attribute named required, we also added it to a :presence validation along side other attributes.
When we tried to create an instance of SurveyQuestion in the console with a required: false value, we got the following exception

1
ActiveRecord::RecordInvalid: Validation failed: Required can't be blank

Obviously, it is there. what happened?

ActiveModel::Validations::PresenceValidator

ActiveModel::Validations::PresenceValidator is the class responsible to handle :presence validations in ActiveModel, there it is:

rails/activemodel/lib/active_model/validations/presence.rb
1
2
3
4
5
class PresenceValidator < EachValidator # :nodoc:
  def validate_each(record, attr_name, value)
    record.errors.add(attr_name, :blank, options) if value.blank?
  end
end

The PresenceValidator basically adds an error when the value of the validated field returns true for #blank? but, the way Object#blank? treats booleans is the way that causes this issue:

Object#blank?
1
2
[1] pry(main)> false.blank?
=> true

Which means, that this is the reason why the :presence validation is failing for boolean fields with a false value, it simply returns true for false values.

Solution

Not really a solution, rather an ugly workaround but the way to get it done is to use the :inclusion validation instead.

survey_question.rb
1
2
3
4
5
6
7
8
9
10
11
class SurveyQuestion < ActiveRecord::Base
  belongs_to :owner, :polymorphic => true
  has_many :dependent_questions, :class_name => "SurveyQuestion", :as => :owner
  has_many :survey_answers
  serialize :options, Hash

  attr_accessible :owner, :owner_id, :owner_type, :question_body, :question_type, :options, :required, :parent_answer_condition, :client_integration_param_name

  validates :question_type, :question_body, presence: true
  validates :required, inclusion: [true, false]
end

I think that a better solution for this problem is to pass the column/field object to the validation as well. It will allow any validator such as PresenceValidator to perform specific validation techniques that match the field/column type – in this case – allowing a boolean field to have a false value.

Installing Ruby 2.0

I had a bit of an adventure this morning getting Ruby 2.0 installed on
my mac with Mountain Lion, so I thought I’d share the tale with you in
case it can help save you some time on doing the same. Up until now
I’ve been developing my Rails apps with 1.9.3, but it was time to
upgrade and experience all the new hotness of the latest Ruby. I had
tried to install Ruby 2.0 before, but I had been stymied by an openssl
error when building. Today was to day to get that sorted.

I’m using rbenv to manage the different Ruby versions on my machine, so
the first step was to update ruby-build, which I have installed via
homebrew, so that I could fetch and build the latest Ruby. Sadly, I had
some weirdness with my homebrew installation that prevented me from
getting the latest homebrew, which prevented me from getting the latest
ruby-build, which prevented me from being able to install the latest
Ruby (2.0.0-p247):

$ brew update
error: Your local changes to the following files would be overwritten by merge:
...

I was pretty sure I hadn’t changed anything in homebrew myself, and I
found some guidance in the github issues list for homebrew that I should
just blow away my local changes with a git reset, which didn’t initially
work because apparently some permissions had changed in /usr/local:

$ cd /usr/local/Library
$ git reset --hard FETCH_HEAD
error: unable to unlink old 'README.md' (Permission denied)
error: unable to unlink old 'SUPPORTERS.md' (Permission denied)
fatal: Could not reset index file to revision 'FETCH_HEAD'.

$ sudo chown -R `whoami` /usr/local
$ git stash && git clean -d -f
$ brew update

Now I was in business. Next up I upgraded ruby-build, and since I had
already installed openssl via homebrew previously, I could use that
while compiling:

$ brew upgrade ruby-build
$ env CONFIGURE_OPTS='--with-openssl-dir=/usr/local/opt/openssl' rbenv install 2.0.0-p247

Boom! Ruby 2.0 was finally installed. But then I hit a snag while
trying to install gems for one of my Rails projects:

$ bundle
Could not verify the SSL certificate for https://code.stripe.com/.
There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about
OpenSSL certificates, see bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.

That was an especially useful error message, since that link provided a
tip on easily getting some updated ssl certificates:

$ brew install curl-ca-bundle

And that tells you to

$ export SSL_CERT_FILE=/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt

And now everything works. Woohoo!

Meet Heroku Events

Throughout the year we participate in a lot of conferences, hackathons, meet-ups, educational programs, and open source projects. At each and every one, we are inspired by the accomplishments, projects, and people we get to meet there. We welcome the opportunity to talk to you about your projects, answer your questions and share some awesome Heroku swag. If you see us at an event, please stop by and say "Hi."

Each month you can find out where Heroku will be by going to our events page, on Twitter, or on Facebook where you can also see where we've been.

So what's happening in August?

The month started off on August 3rd with Richard Schneeman @schneems and Harold Gimenez @hgmnz engaging Ruby attendees at Burlington Ruby Conference in Burlington, VT.

PyCon Canada in it's second year, promises to be a busy one. On August 9th Jacob Kaplan-Moss @ jacobian will be the opening keynote speaker, while Kenneth Reitz @kennethreitz will be "Planting Open Source Seeds" on August 10th. We can also be found in the Expo Hall, where engineers are looking forward to meeting you and talking all thing Python. We are also excited to be supporting the [PyLadies Social[(http://pyladies-at-pyconca.eventbrite.com) this year.

Later in the month and 5,375 miles away, Designer and Node.js buildpack maintainer, Zeke Sikelianos @zeke is speaking at the BrazilJS Conf 2013 one of the world's largest Javascript conferences. He'll be speaking about crowdsourcing Heroku's Node.js buildpack and what we've learned from our open source community.

Please check out our events page for a full listing of upcoming events. See you on the road!

How We Use Heroku Postgres Dataclips to Drive Our Business

Heroku Postgres brings the Heroku flow to your database, offering safe and straightforward provisioning, scaling, development and collaboration. Traditionally, generating and sharing data from within databases has been inconvenient and challenging. What if you could safely and easily capture and share the data you need to drive your business?

Dataclips, available on all Heroku Postgres production and starter databases, let you run SQL queries against your data and share the results in an easy, visual way with your team members.

Dataclips can be downloaded or shared via URLs, are downloadable and exportable in many formats, and are executed via a read-only transaction so your data stays safe. To get started with dataclips, check out our Dev Center article.

Using Dataclips to Make Awesome Business Dashboards

At Heroku, we integrate multiple dataclips into Google Docs Spreadsheets, and use the chart and graphing functionality to create custom dashboards. Recently, we used the GitHub API to extract data about our commits to Heroku repos over the past six months and store them in Heroku Postgres. We used dataclips to generate data for specific queries, such as total number of commits per day, top committers, and longest and shortest commit messages. We then integrated the dataclips into Google Spreadsheet, which automatically updates when new data is available, and used it to generate a dashboard of our GitHub activity over the past 6 months.

Step 1

First, we use dataclips to query the dataset. In this example, we're querying the total number of GitHub commits by our teammates over the past six months, broken down by day.

GitHub

Step 2

When you create a dataclip, you can share the data easily using a URL. You can also use that URL to integrate the data with other business tools, like Google Docs. Generate a new Google Spreadsheet automatically from the drop down menu of your dataclip, or use the importData() function, shown below. This populates your spreadsheet with data from the dataclip, which will auto-update over time:

Google

Step 3

Once your data is integrated with your spreadsheet, you can use the built-in chart functionality to generate robust graphs and visualizations of the data:

Total

Top

Commit

Please note that dataclips should NOT be used as an API. The options for endpoints (JSON, CSV, XLS) are great for low-volume background processes such as lightweight integrations and prototyping APIs, but does not replace a production API.

Internal Use Cases

Here are some other ways we use dataclips internally to drive our business.

Postgres Business Dashboards

Our Postgres team brings together multiple dataclips and integrates them with Google Docs, creating a full business dashboard. We import and graph dataclips related to the core health of the business, including overall revenue, how support issues break down by type of incident, attrition rate over time, database provisioning time, and the top users and customers. This gives us a full perspective into our business at any given time, and is easy to share within our company.

Identifying Platform Abuse

Dataclips also play an important role in identifying and addressing platform abuse. First, we identify trends that are correlated with or suggest abusive behavior such as spamming and phishing. Once we identify pattern that abusive attacks take, we can set up a dataclip that looks for actions matching the pattern. For example, sometimes we see sudden spikes in account creation from certain providers, but no additional platform activity – a pattern that can indicate spam operations. We use the JSON or CSV version of the dataclip to bring this data into abuse prevention apps for closer scanning. The lets our security team work better and faster – we don’t have to hardcode complicated queries into our apps, there is no need to redeploy if we want to change a query, and we don't have to give our security apps full access to the underlying databases – just to the behavior patterns we've identified.

Creating a Data-Informed Business

Data alone isn’t enough to create a business where meaningful metrics and quantitative insights are driving better business decisions, faster. Data must be omnipresent in your culture, easily accessible to all of your team members, shareable within and across departments, and flexible enough to integrate with existing business tools. Heroku Postgres dataclips unleashes your data so your team can put it to work.