Looks like the word is out. We’ll have more news on Tuesday but we want you to know we’re excited about the future. Same services, same Pivotal Tracker, same industry leading development practices – now paired with more resources than ever.
If you are using capybara-webkit gem that you should install QT 4.7+, if you need to use pushState/replaceState. Also defining those functions with mock implementations is another good solution.
Guard with spork takes away a lot of the pain of using spork. Use the gem guard-spork which takes care of building you a sample guardfile. It takes care of restarting the appropriate framework you have in use be it test unit, rspec or cucumber.
We have a View that we want centered on the screen, but that must scroll when there isn’t enough room to show the view fully (for example, when the keyboard is up).
Our first attempt:
<ScrollView android:layout_width=... android:layout_width=... > <View android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </ScrollView>
Unfortunately there is a bug in Android where setting layout_gravity=”center” on a ScrollView’s child causes incorrect scrolling when you start hiding and showing other views in the layout (the ScrollView will get stuck with an offset such that you can’t completely scroll to the top, and you can scroll past the bottom).
Here’s the solution:
<ScrollView android:layout_width=... android:layout_width=... android:fillViewport="true" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" /> <View android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> <View android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <View android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> </ScrollView>
The wrap_content in the LinearLayout is a bit misleading: fillViewport=”true” in the ScrollView will cause its child to always be at least as large as the viewport. (See also Romain Guy’s article about fillViewport.)
At Pivotal, our default choice for CI is Jenkins. I feel that Jenkins does a fine job running builds and reporting on a pass/fail. It also has nice plugins and plenty of features like build labeling and clustering.
JetBrains’ TeamCity has all that, and more!
To be fair, TeamCity is missing some things that Jenkins has. However, I don’t remember what they are because I’ve never used some of the deeper features of Jenkins. One thing TeamCity doesn’t support well is running builds for multiple branches dynamically.
That said, I’m a huge fan of TeamCity. Here’s why.
TeamCity understands your tests. It uses custom formatters for RSpec, Cucumber, TestUnit and Shoulda. This means you get more than just a pass/fail on the build. You get a count of the tests that have run. You also get a count of the tests that failed. Seeing these numbers gives me a warm and fuzzy feeling that I don’t get with any other CI tool I’ve seen.
Because it understands the tests it’s running, it can keep track of them. For each spec, or cucumber step, it knows how many times it’s passed, and how many times it’s failed. And, it shows you the relevant stacktrace for each failure. You can also get statistics on a particular spec or step, like so:
It also knows what commit introduced a new failure. Here’s a shot of TeamCity showing a spec failure. The spec description is shown. Below that is the stacktrace in maroon. And to the right, it is showing that the spec first failed in build #532 with andre’s commit. The spec is still failing 105 builds later in build #637. It’s easy to see the stacktrace from both the first failure and the current failure. And yes, that spec has been broken since September 2011.
TeamCity makes it super easy to investigate what is making a build slow. Here’s a list of tests for the bundler gem, sorted by duration. You can filter, sort, and search the tests to analyze what’s going on.
You also get some interesting statistics at the build level:
The insight and analysis that TeamCity makes possible is extremely compelling. After using TeamCity for a few years, I used Jenkins for a a few months. I really missed all of the features above, and felt a lot less connected to my tests.
Other things I find to be very useful:
- Immediate feedback if a test fails during a build. The build will go red as soon as the first test does.
- If a failing test is fixed in a newly running build, it’ll let you know.
- Besides the awesome insight into your tests, TeamCity has support for larger teams. Users can set or take responsibility for a broken build or individual test. So, it’s easy to keep your team informed about who is working on what.
- RubyMine integration, including pre-tested commits.
- TeamCity is free for 20 build configurations and 3 slave agents.
Full list of features: www.jetbrains.com/teamcity/features
Here’s the demo environment: teamcity.jetbrains.com
DISCLAIMER: I do not work for JetBrains, nor are they sponsoring this post. I do, however, love their products.
The good folks at Railsware do it again. A little while back they released a Mac OSX client called PivotalBooster and just today – they released a very slick Pivotal Tracker Chrome extension called PiRo.
It’s a multi-login/multi-story/multi-project gem (I mean that in the sparkly sense) that lets you do all these things from within the same window. In other words a multipass for Tracker (You know – Milla/the Fifth Element “Leeloo Dallas mul-ti-pass”…).
It also looks great. Give it a shot and if you like it – be a good Tracker citizen and vote up our friends with your stars!
We moved a Rails app into an unbuilt engine of a new blank slate container app to allow new parts of our app to live next to it as engines as well. It has been working great for us!
I have a sample app rails_container_and_engines of the result’s structure on github.
Skip to the pitfalls and discoveries section to read about some of the speed bumps we during our transition. Interested in the why and how? Read on!
As part of the project we had built a web app, a mobile app that talks to the web app’s API, two ETL tools to 1) do the initial data import from the app we were replacing and 2) get data into another of our client’s apps. At this point we knew that we would create one more big web app and several auxiliary apps.
Running up to the decision to using unbuilt engines we had several intense discussions on how to build loosely-coupled, highly-cohesive systems with Rails applications. We saw basically three choices:
- All-in-one app that could get more structure through namespacing of its interals.
- Services (REST or whatever, but) running as separate apps and communicating via APIs.
- Engines running within a mostly feature-less container app.
The two big web apps share several models within the data access layer and use the same data. Because of this we chose the third option and left all of the apps within the same rails code base.
Internal discussions highlighted the costs/benefits of having all of these apps live within their own Rails project versus an engines approach. We feel that by using engines we are getting many of the benefits of a component based architecture without breaking Rails patterns. In addition, we feel that the cost of maintaining individual applications that share a central database or one giant application with less defined components would have been very high.
In order to make day to day development easier, and to avoid the “where do migrations live…” conversation and top level Rails deployment patterns, there is one twist to the architecture: everything resides in one git repo and engines are referenced from a single container application (similar to old school enterprise archive files). Each application is exposed via a unique context or resource identifier (each engine/app could also be isolated per instance via Apache). Here is the directory structure we ended up with:
container_rails_app/ ... app config engines/ etl/ shared_modules/ web_app_1/ web_app_2/ ...
Mike described this pattern in his recent blog posts Unbuilt Rails Dependencies: How to design for loosely-coupled, highly-cohesive components within a Rails application and Rails Contained: A Container for Web Application Development and Deployment. On how to make RubyMine work seamlessly with engines, read my post on IntelliJ Modules in Rubymine.
The steps we took
- Generate a new, empty Rails app
- Within the
enginesfolder, create a new, mountable Rails engine
Copy all the tests from the original Rails app into the test directory and make them green.
Ok. This step is a bit more involved. Essentially that’s it thought. Find some of the pitfalls we ran into described below. Here are a couple of highlights of what needs to happen:
- Copy the files you need for a test to pass and namespace its class
- Start with the model tests and work your way up towards integration and acceptance tests
- Namespace everything with the name of the engine (either by fully qualifying every name – don’t do that) or with the lexical scope trick explained below. This includes tests and all classes.
- Load needed gems explicitly: engines don’t load as much automatically as a Rails app
- Namespace tables and assets
- Copy the old .git directory into the new root folder in order to not loose any history. For us, git was not able to detect the changes as moves in many cases. This is certainly an area where you can improve on our solution!
For us, the real work started after this, when we started pullling out common code into a common models engine and began work on the second app.
We got all the tests to pass before we had namespaced any of the assets or rake tasks. That was an additional search-and-replace heavy step after the actual transition to an engine. It is not necessary right away if you do not have multiple applications at first, but to achieve the full effect, you will need to namespace the things as well.
Pitfalls and discoveries
Modules in your enige are not automatically loaded: make sure you reference them yourself before they are needed in other files.
Rails creates a default
app/assets/stylesheets/application.css file which contains these lines:
/* ... *= require_self *= require_tree . */
If you have this file in your main app, all css files will be compiled into one file. For us, this made almost everything look right. Almost. Little things broke here and there. Our app contained a couple of sections for which the stylesheets were meant to be loaded separately. Add files that you want to have precompiled as individual files to
config.assets.precompile list to have them precompiled into separate files and solve this problem.
Are all your references and associations breaking?
module M class X def use_y Y.do_it! end end class Y def self.do_it! end end end
class M::X def use_y M::Y.do_it! end end class M::Y def self.do_it! end end
The first way sets the lexical scope to the module M as well as to the class Y and allows you to reference other classes in M without their full name. The second way sets the scope only to class M::Y and you have to fully qualify every class name to find it.
Don’t fight conventions
We were using fixture builder and while we were namespacing classes in modules we were trying to override the default table names to not be namespaced… Fixture builder didn’t like that at all. There may or may not be other dependencies that make leaving the conventions hard. So, save yourself the trouble and do the migrations (and stay consistent!) and namespace your tables as well!
They seem to be falling out of favor, which is probably a good thing. With engines they don’t seem to work (well). We ended up getting rid of our last two habtm relationships instead of trying to make them work. Creating the join as a class and adding the necessary has many :through relationships is straight forward enough.
We ended up with one production performance bug due to this: Rails
Engines depending on engines
We used kaminari for our pagination requirements. When our app first became an engine, kaminari stopped picking up our custom views. Instead it used its standard views. The load order got screwed up to which there are basically two solutions:
- require => nil on both engines in the Gemfile and force the correct load order in your app, or…
- avoid name clashes by namespacing your views (which you were going to do anyways, right?)
Shared example groups are a feature of rspec that allow specifying common behavior in a reusable group of specs.
I believe that there is a very specific way in which one can benefit from shared examples groups (and should keep them) and many more in which they come in handy at some point and should be refactored away from as development continues.
When shared examples may seem a good idea
If an application employs mechanisms such as mixins, delegation, or inheritance (which every Rails app by default does…), one can probably find some common behavior. Take a soft-delete functionality for example: specifying for each class that it’s objects are soft-deletable and that
it_behaves_like :soft_deletable seems nice, but comes at a cost (and isn’t appropriate).
Shared examples make for a slow test suite
If there are
n test cases and
m specs in the shared examples, there is a total of
n*m specs that will run. Obviously the shared example saves a lot of spec coding:
m shared specs, and
n references to it. Meaning you need to write only
If, however, it were possible to test the common functionality separately (
m specs) and then test only its integration (
n specs), there would still be
n+m specs to write, but more importantly, there would also be only
n+m specs to execute.
n+m, that’s a huge difference.
How to test common code without shared example groups
There are a couple of ways to test common code without resorting to shared examples.
In your spec, write a test harness class that gets your mixin, delegate, or (abstract) super class. This class only has the abilities of a non-special object and the common code. Testing this class allows testing the common code in an isolated way.
If you happen to be relying on ActiveRecord for your mixin as soft-deletable probably would be, use Temping to create an ActiveRecord object that only has ActiveRecord::Base behavior and that of the common code.
In case you have shared example groups in place, but can’t apply either of the above options, you probably haven’t extracted the code enough yet. Do that first and then come back here and refactor away from the shared example group.
Is a shared example group ever the right thing to do?
Imagine a mixin that has complex interactions with the objects it gets mixed in to, like a
it_behaves_like :fuzzy_matchable. Fuzzy matching will always work in a similar way, but be working on different attributes or methods depending on the object. In this case the interactions between the object and the mixin are important to specify and verify. David Chelimsky describes this situation in his post about specifying Mixins with shared example groups. This kind of complex interaction seems to me to be the only case in which shared example groups are truly beneficial.
Am I missing good use cases of shared example groups here? Where do you use them?
1 week from today at lunchtime (3/15/2012 12:30)
Do I Really Need jquery-ujs.js
If I’m never going to do a remote form do I still need it?
Need a way to differentiate between development/production environments.
Thought about using hostname, ie localhost vs another hostname
EC2 now supports 64bit instances for all instance types
We all weren’t hard-wired to be investors on Bay Street, which is why the Globe and Mail teamed up with Xtreme Labs to bring you the Globe and Mail’s ever-popular Investor section right to your mobile phone.
With the Globe and Mail Investor
app you can now receive up-to-the minute market data from some of the world’s largest stock exchanges, including the TSX, DOW, Nasdaq, and the S&P 500. Keep an eye on your own investments using the ‘My Watchlist’ feature, which allows you to add stocks from your own portfolio for your reference at any time.
Also available in the app is the ‘Latest News’ section that allows you to
stay on top of news stories that may influence your potential investment decisions. Current affairs around the world affect stock and bond prices – so by giving you relavant content to analyze The Globe and Mail Investor app will help you to understand what affects prices. Use this curated news stream to find even the smallest piece of information that could affect your portfolio.
Investing in gold with one of your buddies? Be sure to send them the latest market statistics and news stories using the integrated Facebook and Twitter social media features.
Because we built the app we may be a little bias in thinking it’s the best application out there, but we aren’t the only ones who think so. Globe Investor app was selected by Apple as the top application in the “Best of 2011- Finance” category. We want to congratulate everyone at the Globe and Mail, and everyone who worked on the application at Xtreme Labs. For a full list of winners check out the Apple’s 2011 App Rewind in iTunes.
Our friends at Nokia sponsored our latest Hackathon series by supplying us with 30 brand new Lumia 800 phones. Operating on the Windows Phone 7 platform, these Nokia Lumias nicely highlighted developer ability to create an engaging consumer experience using existing Microsoft tools and technologies such as Visual Studio, Expression Blend Silverlight, and the XNA Framework.
While WP7 is still seen as a new and somewhat unknown platform to many smartphone consumers, at Xtreme Labs we find have recognized that our familarity with other Microsoft tools have flattened the learning curve significantly. In an effort to become more familiar with the platform our software engineers had the chance to participate in an internal, two-part Xtreme-Nokia WP7 hackathon series. Two events took place over two Saturdays in the month of February at the Xtreme head office. The first event was dubbed the ‘Learn and Hack.’ Atley Hunter, a Microsoft WP7 expert, along with our very own Greg Burgoon, ran morning tutorials on the platform. They covered an array of topics like Background Agents, Tiles, Location, Media, and Push Notifications.
The afternoon was spent in experimental creation mode. Given the opportunity to play with knowledge they had learned earlier in the day, the developers were able to start manipulating the code to their will. It was clear by the end of the day that our team was ready for the next event.
The main Hackathon event was held the Saturday after the long weekend. Teams spent the whole day working on assigned features in hopes of creating usable code for future app creation. Paul Laberge and Matthew Rabinowitz from Microsoft, and Chad Saliba from Nokia paid a visit to our office. They toured our facilities and got to see our devs in action.
By the end of the day our developer teams had created four very cool apps, utilizing social integration, location-based services, and media playing. While the specifics are top secret, we can tell you that one team worked on push notifications using tiles, while another created a social alarm clock. Stay tuned for more details on these projects as they become available.
When demos were over and we were all feeling pretty accomplished, we still had one more detail to take care of: giving away six brand new Nokia Lumia 800s. By luck-of-the-draw six lucky developers took home the top prize that Nokia generously donated. In the post-event wrap up, the reviews about WP7, and the Nokia Lumia 800s were overwhelmingly positive. Our developers found the platform easy to to work with and were impressed by the tiles feature, as well as it’s smooth UI which were so brilliantly brought to life by the Lumia’s 16 million colour display.
If you are interested in learning more about the WP7 platform, check out some of Microsoft’s online tutorials.
- Ruby MRI seems to have taken a step back in time, a dangerous, but useful feature (to some) is the goto statement.
It appears that DateTime object has some issues with doing math.
DateTime.now - 1.hour #raises TypeError DateTime.now - 3600 #works as expected 1.hour.class #Fixnum
Reading the CSS property
background-positionin Chrome returns an invalid value. Don’t rely on it.
- Github was hacked! They had a security issue that was a result of
attr_accessiblebeing uses incorrectly. Remember to authorize your SSH keys.
- Need help with cron? Use http://cronwtf.github.com to convert cron into friendly English.
not. It is highly recommended to always use the strict logical operators (
!) because the keywords
not) don’t have the same operator precedence.
- When evaluating variables in strings with
bash, its better to use
$var. The curly-brace allows you to evaluate a variable with copy behind it. For example,
$varasdfevaluate differently because of the expected variable name.
Rails <3.1 has some gotchyas when using
class Note < ActiveRecord::Base has_many :contacts, inverse_of: :note end class Contact < ActiveRecord::Base belongs_to :note, touch: true #for triggering the note observer when the contact is updated end class NotObserver def after_touch(note) note.contacts # does not have the new attributes updated unless you specify the :inverse_of end end # Somewhere in the code... contact.update_attributes....
When table names are not namespaced on a class. What is the best way to work with this if we want table names to be namespaced?
class Foo::Bar < ActiveRecord::Base end > Foo::Bar.table_name == "bars" true
At Pivotal Labs, one of the services we provide our clients is helping them interview and hire. Pivotal Labs and our clients place a strong emphasis on Agile development and its many aspects: Pair Programming, Test-Driven Development, rapid iterations, and frequent refactoring.
ESSENTIAL DUTIES AND RESPONSIBILITIES:
Portico by Exclusive Resorts® www.porticoclub.com is a new private club that provides access to a growing portfolio of incredible luxury vacation homes in the world’s best destinations, combined with personalized pre-trip planning and expert concierge service. Portico leverages the unmatched track record and expertise of Exclusive Resorts®, the company that has set a new standard for luxury travel and has provided more than 150,000 exceptional vacations for tens of thousands of its members and their family and friends.
We are looking for a developer to help create an exceptional, custom-built luxury travel solution for our rapidly growing member base and portfolio of homes. Responsibilities include interpreting requirements to identify and evaluate solution alternatives, developing and deploying high-quality applications. You are expected to consistently produce reliable, scalable, high-performance technology solutions using modern design and development patterns. You will be an integral component of strong, tightly-knit, collaborative development team working with a product owner and other key internal business stakeholders.
- Proven experience in development of flexible and scalable web-based applications
- Passion for technology, specifically software development
- 1+ years of experience with Ruby language and the Rails framework, be proficient with the entire Ruby on Rails stack
- 3+ years of hands-on web development, demonstrating:
- Sound object oriented design skills and knowledge of application architecture patterns
- Proficiency with relational databases, including design and development
- Working knowledge in development of MVC-based web solutions
- Ability and desire to thrive in an Extreme Programming environment, including pair programming
- Competency managing source control and automated build processes
- Excellent analytical and problem solving skills
- Strong communication and interpersonal skills
- Experience with agile software development methodologies such as SCRUM and/or XP
- Working knowledge with test-driven development and related frameworks (preferably with RSpec and/or Test::Unit)
- Working knowledge of associated platforms and technologies, including Linux and Apache
No new faces today
What is the approved way of finding out if a migration is pending? Trying to avoid Heroku restart.
Heroku + submodule: .slugignore is your friend!
Heroku supports git submodules! However, when building your slugs it includes the
.gitdirectory in your submodules. This unnecessarily inflates the slug’s size. To circumvent this make a
.slugignorefile in your app’s root directory add
path/to/submodule/.gitto it. You can also use
.slugignoreto ignore specs, docs, etc…