1

I have Table1 with attribute attribute1, which is an array of integer. My controller allows for one insertion at a time. So, in the controller:

def add_attribute1_item
  table1 = Table1.find(params[:id])
  table1.attribute1 << add_params[:attribute1_item]
  table1.save!
  render json: table1
rescue
  render_errors_for(table1)
end

I want to validate this attribute1_item value, ignoring the old values that have been stored in attribute1 array, e.g. if table1.attribute1 contains 99 and I call the controller add_attribute1_item to add 100, I only want to check whether 100 is valid or not, ignoring 99.

class Task < ApplicationRecord
     .
     .
     .
  validate :attribute1_item_is_valid, if: -> { attribute1.present? }
     .
     .
     .
  def attribute1_item_is_valid
    # validate the item by accessing attribute1
  end

I am unsure with this approach because when I access attribute1 in attribute1_item_is_valid, it is the whole array instead of the new item. Is this approach good enough by calling attribute1.last() or is there a more correct method? thank you

1 Answer 1

1

Instead of trying to validate this in the model, validate the form entry.

Create a model for the form and use normal validations.

class SomeForm
  include ActiveModel::Model

  attr_accessor :id, :attribute1_item

  validate :id, presence: true, numericality: { only_integer: true }
  validate :attribute1_item, presence: true
end

def add_attribute1_item
  form = SomeForm.new(params)
  if form.invalid?
    # render form.errors
    return
  end

  table1 = Table1.find(form.id)
  table1.attribute1 << form.attribute1_item
  table1.save!
  render json: table1
rescue
  render_errors_for(table1)
end
Sign up to request clarification or add additional context in comments.

1 Comment

If you're using Rails 5.1+ use attribute :id, :integer and attrribute :attribute1_item instead of attr_accessor. The attributes api will create attributes that actually behave much like ActiveRecord attributes so that you can call .attributes on the model or serialize it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.