{"id":2949,"date":"2012-07-18T16:46:19","date_gmt":"2012-07-18T19:46:19","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=2949"},"modified":"2012-07-18T16:46:19","modified_gmt":"2012-07-18T19:46:19","slug":"active-record-loves-blocks","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2012\/07\/active-record-loves-blocks\/","title":{"rendered":"Active Record loves blocks"},"content":{"rendered":"

I’d like to start with a question: Have you ever seen code like this?<\/p>\n

\r\nclass User < ActiveRecord::Base\r\nend\r\n\r\nUser.new.tap do |user|\r\n  user.name     = \"John Doe\"\r\n  user.username = \"john.doe\"\r\n  user.password = \"john123\"\r\nend\r\n<\/pre>\n

I have. But what few developers know is that many methods in Active Record already accept a block, so you don't need to invoke tap<\/code> in the first place. And that's all because Active Record loves blocks! Let's go through some examples.<\/p>\n

Using blocks with Active Record<\/h3>\n

When creating an Active Record object, either by using new<\/code> or create<\/code>\/create!<\/code>, you can give a block straight to the method call instead of relying on tap<\/code>:<\/p>\n

\r\nUser.new do |user|\r\n  user.name     = \"John Doe\"\r\n  user.username = \"john.doe\"\r\n  user.password = \"john123\"\r\nend\r\n\r\nUser.create do |user|\r\n  user.name     = \"John Doe\"\r\n  user.username = \"john.doe\"\r\n  user.password = \"john123\"\r\nend\r\n<\/pre>\n

And you can mix and match with hash initialization:<\/p>\n

\r\nUser.new(name: \"John Doe\") do |user|\r\n  user.username = \"john.doe\"\r\n  user.password = \"john123\"\r\nend\r\n<\/pre>\n

All these methods, when receiving a block, yield<\/code> the current object to the block<\/a> so that you can do whatever you want with it. It's basically the same effect as using tap<\/code>. And it all happens after the attributes hash have been assigned and other internal Active Record code has been run during the object initialization, except by the after_initialize<\/code> callbacks.<\/p>\n

That's neat. That means we can stop using tap<\/code> in a few places now. But wait, there's more.<\/p>\n

Active Record associations also love blocks<\/h3>\n

We talked about using blocks when building an Active Record object using new<\/code> or create<\/code>, but associations like belongs_to<\/code> or has_many<\/code> also work with that, when calling build<\/code> or create<\/code> on them:<\/p>\n

\r\nclass User < ActiveRecord::Base\r\n  has_many :posts\r\nend\r\n\r\nclass Post < ActiveRecord::Base\r\n  belongs_to :user\r\nend\r\n\r\n# has_many\r\nuser = User.first\r\nuser.posts.build do |post|\r\n  post.title = \"Active Record <3 Blocks\"\r\n  post.body  = \"I can give tap a break! <3 <3 <3\"\r\nend\r\n\r\n# belongs_to\r\npost = Post.first\r\npost.build_user do |user|\r\n  user.name     = \"John Doe <3 blocks\"\r\n  user.username = \"john.doe\"\r\n  user.password = \"john123\"\r\nend\r\n<\/pre>\n

That's even better. That means we can stop using tap<\/code> in a few more places.<\/p>\n

Wrapping up: Active Record <3 blocks<\/h3>\n

It is possible to avoid extra work, sometimes simple stuff such as using tap<\/code> with methods like new<\/code> and create<\/code>, other times more complicated ones, by getting to know what the framework can give us for free.<\/p>\n

There are other places inside Active Record that accept blocks, for instance first_or_initialize<\/code> and friends will execute the given block when the record is not found, to initialize the new one.<\/p>\n

In short, next time you need a block when creating records using Active Record, take a minute to see if you can avoid using tap<\/code> by using an already existing feature. Remember: Active Record <3 blocks. And don't do that with blocks only, the main idea here is that you can learn more about the framework, and let it do more work for you.<\/p>\n

How about you, do you have any small trick in Ruby or Rails that makes your work easier? Take a minute to share it with others in the comments. \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"

When creating an Active Record object, either by using `new` or `create`\/`create!`, or even through a `belongs_to` or `has_many` association, you can give a block straight to the method call instead of relying on `tap`. It is possible to avoid doing manual work, sometimes simple stuff such as using `tap` with methods like these, or sometimes more complicated things, by getting to know what a framework like Rails can give us for free.<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[106,185,92,7],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/2949"}],"collection":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=2949"}],"version-history":[{"count":26,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/2949\/revisions"}],"predecessor-version":[{"id":2999,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/2949\/revisions\/2999"}],"wp:attachment":[{"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=2949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=2949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=2949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}