Ember Date Picker with Ember Data and Pikaday Mar 27


Atomic Spin has a great article on setting up Pikaday with an Ember.TextField view. However, since I'm using Ember Data with some date attributes, I needed to actually use a Date object rather than a formatted date string. Here's what I came up with after adding a few things to their example:

Ember Starter Kit

There were a couple things I had to add for this to work:

  • I'm using the moment.js library to allow MM/DD/YYYY formatting.
  • I format the existing date in the didInsertElement event handler.
  • Rather than binding the attribute directly to the value, I'm using a date binding instead. This gives me the chance to parse a formatted date before setting the attribute.
  • Two-way binding to the date:
    • The updateDate function, which observes value, directly sets the date to the parsed value.
    • The updateValue function, which observes date, updates the value with the formatted date.


Capistrano 3: Setting a Default Stage Jan 8


In Capistrano v2, multi-stage support wasn't built in. If you didn't need stages, you could just happily use cap deploy without any problem.

Capistrano v3 is a complete rewrite from v2, and with it comes built-in multi-stage support, even if you don't want it. So even if you have just a single stage, let's say production, you still have to reference the stage every single time you run your Capistrano tasks:

1
cap production deploy

If you try cap deploy without a stage, you will be told:

Stage not set, please call something such as cap production deploy, where production is a stage you have defined.

If you used something like the multistage extension in v2, you would expect to be able to add set :default_stage, "production" to your configuration. You will quickly find that this has no effect in v3, and if you try to run your tasks without specifying a stage, you'll get the same error. The issue has been brought up but apparently having a single stage isn't a "use case." I disagree, so let's make it work.


Time to dig into Capistrano a little. Instead of using its own DSL, Capistrano is now a Rake application. So what's really happening is that Capistrano is expecting a separate task for your stage to be run before the deploy task. In fact, the deploy.rb file isn't even loaded when you run cap deploy without a stage.

When we look at Capistrano's lib/capistrano/setup.rb file, we find that the stage tasks do a couple things. For each stage (the list of stages is created from the files in the config/deploy/ directory), a Rake task is defined to:

  1. Set the :stage
  2. Load the capistrano defaults
  3. Load the deploy.rb file
  4. Load the deploy/#{stage}.rb file
  5. Do a couple other things like setting SCM and locales
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# lib/capistrano/setup.rb namespace :load do task :defaults do load 'capistrano/defaults.rb' end end stages.each do |stage| Rake::Task.define_task(stage) do set(:stage, stage.to_sym) invoke 'load:defaults' load deploy_config_path load stage_config_path.join("#{stage}.rb") load "capistrano/#{fetch(:scm)}.rb" I18n.locale = fetch(:locale, :en) configure_backend end end

Now that we know what the stage tasks do, we need to approach it a little differently. Instead of thinking How do I set a default stage, we now ask How do I make sure that my production stage's task is run every time.

Because this is a Rake application, we already know the answer: invoke the production task by default. Normally you would do this from your Rakefile, but since we're using Capistrano, you'll add this to the end of your Capfile instead:

1
Rake::Task[:production].invoke

We can even use the invoke method from Capistrano's own DSL:

1
invoke :production

Note: We could have simply added a shell alias such as alias cap='cap production', but that has plenty of its own downsides.

Also, this may have some unintended consequences if you actually do use multiple stages, but if you only ever use the production stage, it should work fine.



jQuery Mobile Rails 1.4.0 Released Dec 30 2013


jQuery Mobile 1.4.0 has been released, so the jquery_mobile_rails gem has been updated as well!

You can read about the changes on the jQuery Mobile blog.



jQuery Mobile Rails 1.4.0.beta.1 Released Sep 26 2013


I've been helping out with maintenance of the jquery_mobile_rails gem and am excited to announce the first beta for the upcoming 1.4.0 release.

You can read about the changes on the jQuery Mobile blog.



Speeding up Rails 4 in Development Mode Sep 12 2013


As I've been adding more and more CSS/JS files to my Rails app, I've been noticing a huge slowdown in page load times. Most of the assets are tiny controller-specific files, but the size of those files is irrelevant.

By default, Rails 4.0 turns on "debug mode" for your assets. As a result, every single page load sends a separate request for each asset. Even though most of these return a 304 Not Modified header, it still slows things down by having to send/receive a couple hundred requests.

Simply disabling asset debugging in config/development.rb drastically improved the page load time in the browser:

1
2
3
4
# Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. config.assets.debug = false

Note that this is different from production mode; Rails still recognizes when you change your assets and will automatically reload them without needing to restart the server. The primary change is that the CSS/JS is concatenated into single files.

Before the change, Chrome took around 1.8 seconds to fully load a page. After the change, 450ms. Development mode feels much snappier now!



Load Order with RubyMotion May 6 2012


Because of the way RubyMotion compiles your application, you may run into dependency issues between your ruby files. By default, RubyMotion uses a simple Dir.glob command to load your files:

1
Dir.glob(File.join(app.project_dir, 'app/**/*.rb'))

Suppose you create a custom module under app/lib/foo.rb with some convenience methods:

1
2
3
4
5
module Foo def self.bar "bar" end end

And then you include it in your AppDelegate class:

1
2
3
4
5
6
7
8
class AppDelegate include Foo def application(application, didFinishLaunchingWithOptions:launchOptions) @bar = self.bar true end end

When you run rake, you may run into this:

1
2
3
4
5
(main)>> 2012-05-06 16:58:49.270 app[88253:f803] *** Terminating app due to uncaught exception 'NameError', reason: 'uninitialized constant AppDelegate::Foo (NameError) ' *** First throw call stack: (0x156a022 0x1b0cd6 0xd1c34 0x2377 0x2225) terminate called throwing an exception

The basic solution, which RubyMotion's documentation suggests, is to use the app.files_dependencies option in your Rakefile:

1
2
3
4
5
Motion::Project::App.setup do |app| # Use `rake config' to see complete project settings. app.name = 'app' app.files_dependencies 'app/app_delegate.rb' => 'app/lib/foo.rb' end

However, if you are building a large app, and want Foo to be available to all your classes, you probably don't want to have dozens of 'app/baz.rb' => 'app/lib/foo.rb' entries. In my project, I'm just altering the array of files from Dir.glob instead, ensuring my modules get loaded first:

1
2
app.files = Dir.glob(File.join(app.project_dir, 'app/lib/**/*.rb')) | Dir.glob(File.join(app.project_dir, 'app/**/*.rb'))