attr_accessible is gone
The strong_parameters gem has been integrated into rails edge by DHH and replaces attr_accessible.
Capybara's should_not have_css visibility: false
Capybara's "should_not have_css "#whatevs", visibility: false" results in flaky tests if the content in question is being hidden after a process completes (such as an AJAX request).
An alternative is "should_not have_selector "#whatevs", visible: false". This results in substantially less flaky integration tests.
ActiveSupport::Notifications implements Pub/Sub
iOS6 Safari Caching POSTs
Workarounds needed until bug is fixed.
Tuesday: NYC.rb Hackfest
Tuesday: Brown bag on ThreeJS (WebGL)
On a client project recently, we ran into a domain problem that didn't fit into the ActiveRecord standard conventions. The following is the thought process taken to get to our solution, so it gets detailed in some areas.
ActiveRecord has a great feature called Single Table Inheritance. It allows a model to have multiple types while using a single database table for the storage. Those type abstractions can each have their own validations, override base functionality, and specific abstraction functionality.
If your model has ever been littered with
case statements checking if a
User is a guest, admin, etc., you should take a look at STI.
The project had a based model that had many types and each abstraction had a scope of
.active that defined what it meant to be active for that type.
class Person < ActiveRecord::Base; end class FireFighter < Person def self.active where(has_helmet: true) end end class PoliceOfficer < Person def self.active where(has_squad_car: true) end end
We needed to create an API endpoint that returned all active
Person instances. This would require us to iterate through each child of
Person and get all its current active members. Since we have
Person model let's give it a concept of
.active that incorporates every active member of society in our domain.
We can extend
Person to return an array of each active
class Person < ActiveRecord::Base def self.active FireFighter.active.all + PoliceOfficer.active.all end end
One problem we have with this implementation is every time we add a new abstraction of
Person we have to add to
.active. Luckily, ActiveRecord STI comes with support for looking up a parent's
class Person < ActiveRecord::Base def self.active active_people = descendants.map do |descendant| d.active.all end.flatten end end
This is pretty powerful. We can add
Astronaut and any active astronauts will automatically be in
Person.active array. This implementation will help satisfy our API endpoint requirements, but it does break useful ActiveRecord patterns.
WARNING: Continue at your own risk. If you are content with the solution above stop, but if you want to see what can be done with Arel continue.
What if we want to chain scopes or extend the
.active with pagination for our API? We cannot do this because easily because we are currently returning a Ruby array instead of an ActiveRecord::Relation. How can we modify
.active to be an actual scope?
You might be thinking, ActiveRecord comes with the ability to merge scopes between models. Unfortunately, it does not work very well when merging scopes with STI models.
We ended using Arel (known for not being well documented) within our model. Each ActiveRecord::Relation is actually just an object with holding on to Arel values for different parts of an SQL statement -- joins, froms, selects, etc. We are able to get the conditions for
WHERE clause by looking at the ActiveRecord::Relation
class Person < ActiveRecord::Base def self.active conditions = descendants.map do |d| d.active.where_values.reduce(:and) end.reduce(:or) where(conditions) end end
Our implementation takes the
where_values from the
.active scope from each descendant and does an SQL
OR on them. ActiveRecord::Relation can take
# somewhere in a Rails console > Person.active.to_sql => SELECT "people".* FROM "people" WHERE ( ("people"."has_helmet" = 't' AND "people"."type" = "FireFighter") OR ("people"."has_squad_car" = 't' AND "people"."type" = "PoliceOfficer") )
What does give us? We can now use
Person.active as a normal scope, which allows us to append any conditions on to it.
> Person.active.where(created_at: 2.days.ago..1.day.ago).order(:created_at) =>  > Person.active.limit(10) => 
I've been trying to learn RubyMotion recently, using Ruby to develop iOS appeals to me.
I have no prior Objective-C or Cocoa API knowledge besides the basic HelloWorld. I've been using this tutorial and have learned more about Cocoa API faster using Ruby than with Objective-C. There is less boilerplate code that needs to be written for defining interfaces and implementations.
The main takeaway of RubyMotion is that it is not your standard Ruby implementation. It is a Ruby runtime wrapped around the Objective-C runtime. All Ruby objects map directly to there corresponding Objective-C object -- Array to NSMutableArray, Hash to NSMutableDictionary, etc. RubyMotion does not come with the standard library as other flavors, you are relying on Cocoa API as the standard library.
There is even a difference in Ruby syntax to map directly to Objective-C. The Objective-C language does message passing for "method invocation". This means that a method call on an object is determined by parameters rather than just method name. RubyMotion had to include this language feature, so you will actually see Ruby that is invalid all other Ruby flavors.
class MyObject def doSomething(doSomething, argument: argument) end #This does not override the method defined above def doSomething(doSomething, anotherArgument: argument) end end
Luckily there are extensions for your favorite editors. Rubymine even supports MacRuby syntax, but does not support autocomplete, yet.
Two weeks ago, I saw a talk about RubyMotion from its creator in Berlin. He gave the basic HelloWorld demonstration, but also gave an introduction in the community. It is small, but great things are coming out of it.
The community has started taking the power of Ruby and making the libraries and DSL-y things we love in Ruby.
- BubbleWrap is a resource API. It gives you easy access to JSON parsing, HTTP requests, alerts, etc. It is kind of catch all of lower-level Cocoa API tasks that you don't want to have to write your own helpers for.
- Formotion is a DSL to create Forms. Usually you use Interface Builder to build forms and load the appropriate NIB. This gem will allows you to define a form in code.
- MotionData is ActiveRecord like access to CoreData. It supports migrations, scopes, basic validations, etc.
- SimpleView provides a DSL for formatting views.
With all this, there is one question that always gets asked. Is RubyMotion worth it? Yes! Laurent, the creator, is in it to win it! This is why he charging for the RubyMotion; funding ensures that he can continue to work on it.
RubyMotion comes with a prebuilt RSpec (actually a port of bacon) like testing framework. The testing framework supports the testing of views and controller using the UIAutomation framework. I think that we can agree that it could be better, but I believe there is enough to get started and allow us to expand on it.
The RubyMotion community is still growing. I look forward to see what comes out of it, so that I can use Ruby in other devices.
- 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
validateson an association, remember for uniqueness validations to use the associated attribute.
validates :foo, :uniqueness => true
validates :foo_id, :uniqueness => true
You can get a quick an easy
git blamewith a string, rather than a line number.
git log --pretty=oneline -S'some string'
What is the advantage of using
scopeover a class method?
scope :new, order(:id)
def self.new order(:id) end
Some Pivots seem to think that
scopedoesn't add the default scope in some cases (a bug?). It appears that class methods are the preferred way moving forward in Rails.
- Tuesday brown bag was a series of Youtube videos of Alan Key speaking about programming.
- Thursday UX Book Club is meeting to discuss Steve Jobs book.
- Trying to load Ruby 1.9.3 with RVM on OSX Lion and having problems? Adam has found a solution here.
- Simple made easy was the tech talk (video) today. The implications being what is easy might not be the best for your code maintenance.
- Git 1.7.8 is out!
- We have a new gong in the office!
- When using
Timecop.timetravelin your tests, make sure that you use before setting up your test data. Otherwise the data could potentially be created before that time existed!
git whatchangedgives you a normal
git logwith a list of changed files.
- Rails console history is crazy! On opening a new session, and pressing up for history, random data appears from history, many eons ago. Two files are written to with each rails command -> irb_history and irb-history. Any idea what's going? Some people think that it might the interaction with wirble.
- If you are trying to get REE on Lion make sure that you have GCC 4.2 or higher. Learn more.
- If you are still using a mouse with scroll wheel in Lion, disable the middle click annoyance with Mission Control.
- Donate for Movember we are team 'Pivots NY'. We grow facial hair for Man Cancer Awareness Month.
- Heroku has released Scheduler. Their replacement functionally for cron, which allows you to schedule processes to be run (limited to a 10 minute interval).
- Monday - Raise Cache @ 7pm
- Wednesday - node.js meetup @ 6:30pm
- Wednesday - Machine Learning study group @ 7pm