Can I Populate / update a new record after using find_or_initialize_by with one line like when using new()?

2k Views Asked by At

I am in the process of changing some functionality and as such, I want to use find_or_initialize_by to replace new

My modal has 13 columns

modal = Modal.new(col1: col1, col2: col2..... col13: col13)

The new code is:

modal = Modal.find_or_initialize_by(col1: col1, col3: col3)

and now I need to either populate or update the remaining 11 columns.

Can this be done on one line? I would rather not write:

modal.col1 = col1
modal.col2 = col2
....
modal.col13 = col13

Thanks

1

There are 1 best solutions below

4
Sophie Déziel On BEST ANSWER

You can pass a block to set the attributes to the new records. This is useful when you want to create them with some values and you don't want to override the existing records.

modal = Modal.find_or_initialize_by(col1: col1, col3: col3) do |record|
  record.col4 = col4
  record.col5 = col5
  # etc
end

You can play with its syntax to oneline it, using #attributes=:

modal = Modal.find_or_initialize_by(col1: col1, col3: col3) { |r| r.attributes = { col4: col4, col5: col5 } }

Note that #attributes= will only set the values, you have to manually save. If you use .find_or_create_by instead of .find_or_initialize_by, it will validate and save the new record after the block's execution.

If you want to set the attributes the record, regardless if it's new or not:

modal = Modal.find_or_initialize_by(col1: col1, col3: col3)
modal.attributes = { col4: col4, col5: col5 }

You can also use #update_attributes, but your record will be validated and saved.

modal = Modal.find_or_initialize_by(col1: col1, col3: col3)
modal.update_attributes(col4: col4, col5: col5)