Rails find_or_create_by more than one attribute?

tybro0103 picture tybro0103 · Jun 15, 2010 · Viewed 105.1k times · Source

There is a handy dynamic attribute in active-record called find_or_create_by:

Model.find_or_create_by_<attribute>(:<attribute> => "")

But what if I need to find_or_create by more than one attribute?

Say I have a model to handle a M:M relationship between Group and Member called GroupMember. I could have many instances where member_id = 4, but I don't ever want more than once instance where member_id = 4 and group_id = 7. I'm trying to figure out if it's possible to do something like this:

GroupMember.find_or_create(:member_id => 4, :group_id => 7)

I realize there may be better ways to handle this, but I like the convenience of the idea of find_or_create.

Answer

x1a4 picture x1a4 · Jun 15, 2010

Multiple attributes can be connected with an and:

GroupMember.find_or_create_by_member_id_and_group_id(4, 7)

(use find_or_initialize_by if you don't want to save the record right away)

Edit: The above method is deprecated in Rails 4. The new way to do it will be:

GroupMember.where(:member_id => 4, :group_id => 7).first_or_create

and

GroupMember.where(:member_id => 4, :group_id => 7).first_or_initialize

Edit 2: Not all of these were factored out of rails just the attribute specific ones.

https://github.com/rails/rails/blob/4-2-stable/guides/source/active_record_querying.md

Example

GroupMember.find_or_create_by_member_id_and_group_id(4, 7)

became

GroupMember.find_or_create_by(member_id: 4, group_id: 7)