– we create awesome web applications

Astrails, the oldest, most renown, experienced and just plain awesomest Rails development studio in Tel Aviv is looking for an experienced, nay, fuck experienced, passionate web developer.

We work with Rails since 2005, done more than a hundred projects for startups from all over the world and work with the newest and most interesting technologies around. We constantly speak at conferences and literally wrote a book about Rails.

We are 7 industry veterans, have shitloads of knowledge accumulated and happy to share it. We routinely do code reviews, pair programming and automatic testing. We work with best tools money can buy and have unlimited educational budget for everyone.

Long story short, if you want to learn and advance as a developer, there is no better place to be, period.

We’re looking for a web developer that loves the craft. If you can loudly argue about advantages of client vs server side rendering, NoSQL vs relational DB, Ruby vs Python, do apply, you’ll find who to argue with here :)

If your idea of a job is punching a card and being done with it, go to Microsoft or something, it will not work out here. But if you’re enthusiastic about technology, spend your time reading dev news, come talk to us, we speak the same language.

What you get:

  • You will work with cutting edge technologies and people that care about them
  • You’ll get to know a lot of emerging startups, the world startup scene and never get bored
  • You get a Macbook Air, 27” kick ass Apple Cinema Display and an Apple keyboard and mouse to go with it
  • You will work in a cool office with a fridge full of good stuff and the best coffee we can find

What we want:

  • some 2-3 years of web development experience, if it was Ruby or Python - big fat plus
  • strong understanding of front end development, JS, jQuery, Backbone.js, HTML5, CSS3 should be something you can tell us about
  • we will strongly prefer someone who has github account, contributes to some open source project, did some pet projects at home, runs a blog about development, tweets about related stuff, you get the idea.

Sounds like your cup of beer? [email protected]

It’s alive. Again ;)

This blog was dead for a while. It was running on an old Mephisto system and it’s admin interface just broke one day, throwing some cryptic exception.

It was probably not that hard to fix, but every time I thought to write a blog post it was like “oh, I have to dig into this antient codebase to figure out how to fix it before I actually get to write anything. I’ll pass…”

So days become weeks, and weeks become months, pretty fast its a year that passed by with no blog posts whatsoever.

Meanwhile I was scribing my thoughts on future blogposts in markdown files on my harddrive.

Not long ago we finally decided to do something about it.

Getting the data out.

First we had to get the data out of the mephisto databse. We had to write our own script as whatever we could find on the net was broken in one way or another.

We dumped all articles into simple text files.

Most of the articles were in markdown format but some had to be converted from textile.

Deciding where to have the new blog.

We couldn’t decide for a long time. There were a couple of options:

  1. standalone static site
  2. something under /blog/ directory in the current astrails.com site which was implemented in Rails.
  3. 3rd party service.

I was for option 2 since I think its the best one for SEO and also gives us complete control over the style, syntax coloring, urls, smart sidebar and footer and whatnot.

But we went with options 3 at first, as it seemed the fastest one, and created a blog on Tumblr.

Now, Tumblr is a nice service, even though we didn’t intend to use its community features, we just needed a blog. Quite a few high profile ruby people and companies use it, for example Thoughtbot and many others.

But we immediately hit a couple of problems with it.

First, it doens’t let you completely control your urls, so we would have to redirect old blog post urls to not break linkbacks and not to be punished by Google and friends. Fortunately it does allow to define redirects, but the process is rather cumbersome, and lets face it nice urls are, well, nice ;)

We did manage to import our old blogpost into it using their API but we had to manually fix some styling later and once we discovered that some blogposts had content problems and we had to re-run the import script again (which means repeating the manual formatting again too), we decided to look again at the option 2.

integrating blog into existing Rails app.

The hardest part was to convert the old app to Rails 3.2 as it was still running on Rails 2. After that it was not that hard at all.

Note: the code below is somewhat simplified, we did end up adding things like filtering by tags, authors and atom.xml support.

It all is built around model Post:

class Post

  def self.model_name
    ActiveModel::Name.new self
  end

  ...

end

model_name is needed so that we can just pass a post into link_to like so:

link_to post.title, post

What else is there?

We decided to just commit the markdown files under directory blog preserving the old url s tructure. So that, for example, a blogpost that was at http://blog.astrails.com/2008/6/4/being-lazy-with-ruby would go into blog/2008/6/4/being-lazy-with-ruby.html.markdown.

Enumerating the files.

Once the files were in place we needed a way to enumerate them all to build the blog’s index pages:

# This is just an quick and UGLY hack ;)
def self.filenames
  @@filenames ||=
    Dir['blog/20*/*/*/*.html.markdown'] .
    map {|f| f.gsub("blog/", "")} .
    map {|f| y, m, d, p = f.split("/", 4); [y.to_i, m.to_i, d.to_i, p.split(".", 2).first]} .
    sort .
    reverse .
    map {|f| f.join("/")}
end

Its a quick and dirty way to sort all the blogposts chronologically according to their path.

Post.find and friends

Next, lets try to make it behave somewhat like an ActiveModel (Note I didn’t use the actual ActiveModel since I really wanted to keep this to a bare minimum), I did ‘emulate’ the interfaces I was going to use so that it will be trivial to convert to ActiveModel later.

attr_reader :id
def initialize(id)
  @id = id
end

def self.index
  @@index ||= filenames.inject({}) do |all, file|
    all[file] = Post.new file
    all
  end
end

def self.all
  index.values
end

def self.find(id)
  index[id] or raise ActiveRecord::RecordNotFound.new(id)
end

def self.first
  find filenames.first
end

Post#content

Once we have the blog posts indexed, we need to get the content

def path
  @path ||= File.join(Rails.root, "blog/", "#{id}.html.markdown")
end

def content
  @content ||= File.read(path)
end

Metadata

Besides the content we also need things like title, author, tags etc.

We decided to use a YAML prefix to all markdown files, similar to what Jekyll does. The YAML is separated from the rest by an empty line:

def parse
  return if @body # already parsed
  meta, @body = content.split("\n\n", 2)
  @meta = YAML.load(meta).with_indifferent_access
end

def body
  parse
  @body
end

def meta
  parse
  @meta
end

Markdown rendering

Now that we have the content parsed we need to render the markdown and with syntax highlighting.

After some investigating we decided to use Redcarpet gem for markdown and Albino for syntax coloring.

application_helper.rb

def markdown
  @markdown ||= Redcarpet::Markdown.new(
    AlbinoRenderer,
    :space_after_headers => true,
    :fenced_code_blocks => true)
end

def format_markdown(text)
  markdown.render(text).html_safe
end

Syntax highlighting

AlbinoRenderer turned up a little more complicated then the standard examples found on the net as we wanted to:

  • support both code blocks and in-line code fragments
  • a simple syntax to declare language without using the fenced_code_blocks.

A fenced code block is a markdown extension of Redcarpet. The syntax is as following:

This is markdown text.

~~~~ruby
Here goes the ruby code
~~~~

The problem with it was mostly aesthetics ;). Vim markdown wouldn’t recognize it as code and would freak out on underscores and such as an invalid markdown syntax. So I wanted to use the standard 4 space indentation for code blocks, but still be able to declare the language.

The syntax that was implemented is like this:

This is markdown text.

    #!ruby
    This is a ruby code

albino_renderer.rb:

class AlbinoRenderer < Redcarpet::Render::HTML
  def detect_language(code)
    lang, rest = code.split("\n", 2)
    return code unless lang =~ /^#!\w+$/
    return rest, lang[2..-1]
  end

  def block_code(code, language)
    unless language
      code, language = detect_language(code)
    end
    if language.present?
      Albino.colorize(code, language.presence)
    else
      %Q{<div class="highlight"><pre>#{code}</pre></div>}
    end
  end

  def codespan(code)
    code = code.strip
    if code.starts_with? '#!'
      language, code = code.split ' ', 2
    elsif code.starts_with? '\#!'
      code = code[1..-1]
    end

    if language
      code = Albino.new(code, language[2..-1]).colorize(:P => "nowrap=true").strip
    end
    %Q{<span class="highlight">#{code}</span>}
  end
end

Controller and routing.

We now have all the pieces, lets glue it all together:

config/routes.rb:

match "/blog" => "posts#index"
match "/blog/:year/:month/:day/:id" => "posts#show"

posts_controller.rb:

class PostsController < ApplicationController
  caches_page :only => [:index, :show], :gzip => :best_compression
  layout "blog"

  def protect_against_forgery?;false;end

  def index
    @posts ||= Post.all
  end

  def show
    id ||= [params[:year], params[:month], params[:day], params[:id]].join("/")
    @post = Post.find id
  end
end

Redirecting the old blog urls

Now that the blog has moved to the new home, we need to redirect the old urls.

At first I tried with Rails 3 constraints (I know, its kind of long, but that was a debuggin version, where I wanted to print every segment):

# redirect from blog
constraints :subdomain => /blog\.?/ do
  match '(*path)' => redirect { |params, req|
    subdomain = req.subdomain.gsub(/^blog\.?/, '').presence
    domain    = req.domain
    path      = ['blog', params[:path].presence].compact * "/"
    query     = req.query_string.presence
    host      = [subdomain, domain].compact * "."
    url       = ["http://#{host}/#{path}", query].compact * "?"

    URI.escape url
  }
end

The problem with it was that whenever a page was page-cached, like public/index.html, it would be returned before it hits Rails routing, so http://blog.astrails.com/ would not redirect displaying http://astrails.com content instead.

So instead we ended up with a Rack redirector:

in config/application.rb:

config.middleware.insert_before 0, 'BlogRedirector'

blog_redirector.rb:

class BlogRedirector
  def initialize(app)
    @app = app
  end

  def call(env)
    request = Rack::Request.new(env)
    if handle?(request)
      [301, {"Location" => redirect_url(request)}, self]
    else
      @app.call(env)
    end
  end

  def each(&block)
  end

  protected

  def redirect_url(request)
    request.base_url.sub("//blog.", "//") + "/blog" + request.fullpath
  end

  def handle?(request)
    request.host.starts_with?("blog.") && "/robots.txt" != request.fullpath
  end
end

Making it look like a blog

Now, all this low level stuff is cool, no arguing about that. But someone will have to read it and that means it has to be readable and look like a blog.

We used twitter bootstrap for layout and general structure and styled it to our liking, added a photo of an author to make it personal, big fat date for each blog post so you can keep track, sidebar with tags filtering and some useful links etc.

Now, we no designers here, but i think it looks ok. Am i wrong here?

And we blog again

Now we can avoid using 3rd party blog admin interfaces, one stranger than another. We use Vim to throw down markdown blog posts, along with relevant code pieces and it’s all get rendered and cached as it should.

Writing posts is a nice and simple experience, using familiar tools is warm and cozy, so, we’ll see you soon.

I had a lot of things to do last Thursday, Feb-17. I met a friend from abroad 3am at Ben Gurion Airport and spent several hours talking before we went to sleep, signed a contract for developing killer web app at 1:30am, and finally gave a presentation at The Junction at 4:30pm.

Late evening I found myself thinking (again) about having at least 32 hours days to have enough time to accomplish all the planned tasks. As a developer I always kept a lot of todo tasks in a queue: some ideas about adding new cool features, some ideas about improving existing ones, some thoughts about refactoring. Unfortunately the queue tends to overflow and todo tasks get lost.

There are two ways to solve that.

  1. Have a large manageable queue by using modern project management tools and write everything down naively thinking you would get back to these task later.
  2. Adopt adaptive development approaches and use the right tools to develop web applications like Ruby on Rails, stay productive and happy.

Back to the presentation at The Junction. It has 3 parts:

  1. The Modern Approach: The modern approach of building applications. Creating products using adaptive development methodology allows getting faster to the market while keeping highly maintainable code. Methodology and technology aspects of creating awesome applications in a modern environment.

    Slides are here.

  2. Introduction to Ruby On Rails, a web development that doesn’t hurt. Why Ruby On Rails is so popular among startup founders and developers. What’s so special in web applications framework and general purpose language that makes them the ultimate choice for the next killer application.

    Slides are here.

  3. Case study: thounds.com

    Slides are here.

I hope that those who attended the meetup enjoyed it, and those who didn’t would take a look at the slides.

Vitaly gave an interesting presentation about MongoDB at Database 2011 Conference.

MongoDB. NoSQL for SQL addicts.

Slides are here.

We presented on IGTCloud Ruby On Rails Day today.

Agenda was a bit different this time, not only technical presentations but also a few words about modern approach of building web applications.

Find the slides below.

  1. The Modern Approach - Michael Mazyar

    The modern approach of building applications. Creating products using adaptive development methodology allows getting faster to the market while keeping highly maintainable code. Methodology and technology aspects of creating awesome applications in a modern environment. Slides

  2. Introduction to Ruby On Rails - Boris Nadion

    Web development that doesn’t hurt. Why Ruby On Rails is so popular among startup founders and developers. What’s so special in web applications framework and general purpose language that makes them the ultimate choice for the next killer application. Slides

  3. Ruby Basics - Vitaly Kushner

    General overview of Ruby language.

  4. Rails Basics - Vitaly Kushner

    General overview of Rails framework. Slides for both presentations

  5. Case study - Michael Mazyar

    Adaptive development and Ruby On Rails - real world examples.

The OPEN 2010 conference was very well organized and had many interesting talks.

READ MORE

We are giving 4 out of 20 sessions at Open 2010, an Israeli open source conference.

READ MORE

http://markupslicer.com

Supports ERB and HAML for now, vote on site for more formats.

Beautifully crafted, totally free and it’s kinda fun.

READ MORE

About a week ago about 15 people were gathered in People and Computers offices thanks to Raphael Fogel.

READ MORE

If you follow us on twitter (@astrails if you wondering) you already know that we are at the Startup Weekend Israel right now.

Which is going amazing by the way, thanks for asking, lots and lots of nice people, very creative and energetic atmosphere, food and beer.

Turns out our idea attracted a great team of developers, designers and business developers.

READ MORE

This is going to be the first part of a blog post series about javascript widgets.

First type I’m going to cover is Popup Widget. Sometimes it’s called Popin Widget because there is no actually new window that pops up, instead the content is shown IN-side a current page. The idea is quite simple: you provide some html/js snippet to other sites. They put it into relevant place, and you have some functionality of your site running there.

READ MORE

Everyone needs a backup, right? Unfortunately almost no one does though. Why?!

We needed something for ourselves and our customers. Something simple, free, configure-and-forget. Most of the time there is no need for something fancy, a simple tar + mysqldump can do the job for many small/medium sites.

READ MORE

We participated in JRuby on Rails with GlassFish Code Camp hosted by Sun Microsystems Inc. I was speaking about the framework in general trying to infect Java developers with Ruby On Rails. Slides are available.

Amit Hurvitz gave exciting presentation about GlassFish and short introduction into DTrace. Find out more details about the Code Camp.

READ MORE

2008 was the year when we finally switched to full time consulting. And like all consulters we faced the problem of correct pricing. There are two well-known ways to charge a customer: per-hour rate and fixed bid quote, and several combinations of them.

READ MORE

Blog moved to Mephisto. So we have comments now.

READ MORE

We just incorporated our own Ltd. company.

It was coming for a while now but we finally got to it when we started to hire people :)

READ MORE