Defaultblog

Ruby on Rails QuickTip: Adding Parameters to your Methods Safely

ruby ruby on rails software

This is going to be a quick post and applies to a lot of different languages, but it's something we've been doing in our Rails projects a decent amount.

If you're ever working on a larger codebase and you decide you want to add a parameter to a method, but are afraid to do so because it might break code elsewhere, consider simply adding a default value.

Take the following setup for example

class MyModel < ApplicationRecord
  def my_method(user_id)
    user = User.find user_id
    user
  end
end

Now, let's say you want to modify this method so you can add another parameter. Here's a safe way you can do it:

class MyModel < ApplicationRecord
  def my_method(user_id, new_parameter=nil)
    user = User.find user_id
    if new_parameter
      do something
    end
    user
  end
end

Now that new parameter's default value could have been anything, but the key here:

  1. Have a default value so that any code calling this method with the original parameters will still work
  2. When the new parameter is not passed in, have the method behave the exact same way it did before

With these two principles you'll be able to extend your code without breaking any existing code.

Caseyli
Casey Li
CEO & Founder, BiteSite
Ruby on rails accepts nested attributes for deleting records

Ruby on Rails accepts_nested_attributes_for is deleting my associated record!

ruby on rails software

So I've been programming Ruby on Rails for about 9 years now and I'm still learning new things everyday. This is one that definitely caused us some issues.

Setup

So here's the setup. We have a User model

class User < ApplicationRecord
  has_one :profile, dependent: :destroy
  accepts_nested_attributes_for :profile
end

And we have an associated Profile model

class Profile < ApplicationRecord
  belongs_to :user
end

Notice that on the User model, we have

accepts_nested_attributes_for :profile

If you don't know what that does, it basically allows you to run creates and updates on the User model and Profile model in one single call. So for example, you can do this:

user = User.first
user.update({ email: 'test@example.com', profile_attributes: { first_name: 'Casey', last_name: 'Li' })

If you set up your form correctly and with proper strong params, you can put the User and Profile all in one single form for the user making it easy to update both models at the same time. BUT BE VERY CAREFUL!

Problem

If you have a very similar setup to what we had, basically a one-to-one relationship, then you have to be very careful of your update calls. If you call update on the parent record (in our case the User record), and pass in child attributes, if you DON'T pass in the ID, it will actually delete your existing child record and create a new one!. Yah. I didn't know that either. Try it out, and look at your Rails logs, you'll see a SQL delete statement followed by an insert.

Again, this is for one-to-one relationships only while doing accepts_nested_attributes_for updates.

Solution

If this is the behaviour you want, obviously you're ok. But for us, we wanted to update the existing child record rather than destroying what already existed.

If you want to update the existing record, there are two things you can do.

Solution 1: Pass in the ID of the child record

While I haven't tried this myself, if you pass in the child record's ID, it should perform an update rather than a delete/insert.

user = User.first
profile = user.profile
user.update({ email: 'test@example.com', profile_attributes: { id: profile.id, first_name: 'Casey', last_name: 'Li' })

Solution 2: Use the 'update_only' option

This is the solution we went with. When declaring your accepts_nested_attributes_for, you can pass in the update_only option:

class User < ApplicationRecord
  has_one :profile, dependent: :destroy
  accepts_nested_attributes_for :profile, update_only: true
end

Learn something everyday. Hope this helps out some peeps. Thanks for reading!

Caseyli
Casey Li
CEO & Founder, BiteSite
Thatsawrap 600x600

That's a wrap.

video production business

With 7 great years of producing video under our belts, I have decided to shutdown the Video Production side of our company. BiteSite will now focus solely on Custom Software.

I am extremely proud of the team we built, the work that we’ve done, and the efforts we made to make a great video production company.

On behalf of the BiteSite Video Production team, I want to thank everybody who supported us - our partners, our volunteers, our interns, our clients, and everybody who helped make this possible.

I also want to take this time to personally thank my team. Brendan McNeill helped us produce and land some of our biggest contracts. Jason Connell helped us design, sell, and execute a great new offering. And last but not least, Tim Clark, the most senior employee at BiteSite, really helped me build the video production business to where it is today. I really couldn’t have done this without you guys.

As mentioned, BiteSite will continue on, focused solely on Custom Software - building websites, web applications, and mobile applications.

Thank you.

Caseyli
Casey Li
CEO & Founder, BiteSite

Our Favourite Videos (that we've worked on)

corporate video video production

While the norm is usually "go go go", sometimes it can be pretty cool to look back on the work you've done. As filmmakers, that's what we're doing today! We've had the pleasure of working with some awesome people and businesses over the years to create videos that we (and we hope everyone) are proud of. In this video, we make our picks for the video we enjoyed working on the most as well as a runner-up. While it's hard to nail down the true winners, we did our best... check out the results below.

Tim's Picks

Top Pick - FileFacets Explainer Video

Runner Up - Curtiss-Wright TLCM Video

https://www.curtisswrightds.com/content/videos/Curtiss-Wright_TLCM_Video-1080p.mp4

Casey's Picks

Top Pick - The 2016 L-SPARK Cohort Grad Video

The 2016 L-SPARK Cohort from L-SPARK on Vimeo.

Runner Up - App8 Promo Video

Jason's Picks

Top Pick - Rewind Training Video

Runner Up - App8 Promo Video

Timclark
Tim Clark
Filmmaker, BiteSite

Filmmaker Spotlight - Tim Clark

This post features an interview video with Tim Clark on what he enjoys most about video production. Besides the interview, Tim takes us behind the scenes on the video itself and what went into creating the special effects that you'll see. Special mentions include Adobe After Effects, C4D Lite, Blender, and Element 3D. Stay tuned for more!

Timclark
Tim Clark
Filmmaker, BiteSite