rails icon indicating copy to clipboard operation
rails copied to clipboard

Active Model Dirty: attribute_changed? options (from/to) do not accept symbol

Open thomasvanholder opened this issue 1 year ago • 1 comments

Steps to reproduce

The attribute_changed? receives optional options, such as from and to. Each option key is passed a value. Only string values are accepted, and symbols are not recognized. This is inconsistent behavior as updating a column using the update method does accept both a string and a symbol.

Source code: attribute_changed?

# frozen_string_literal: true

require "debug"
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "activerecord", "~> 7.0.0"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
    t.column :status, :integer, default: 0
    t.date :review_date
  end
end

class Post < ActiveRecord::Base
  enum :status, {draft: 0, published: 1}

  before_update :set_review_date

  def set_review_date
    # when "published" is set as a string, the test correcty passes.
    if status_changed?(to: :published)
      self.review_date = Date.today
    end
  end
end

class BugTest < Minitest::Test
  def test_set_status
    post = Post.create!
    post.update(status: :published)

    assert_equal "published", post.status
  end

  def test_sets_review_date
    post = Post.create!
    post.published!

    assert_equal "published", post.status
    assert_equal Date.today, post.review_date
  end
end

Expected behavior

The value of the optional arguments from and to accepts both a string or symbol.

Actual behavior

When options, such as from and to are passed to the attribute_changed? method the arguments are not recognized when passed as a symbol.

System configuration

Rails version: Rails 7.0.3

Ruby version: ruby 3.1.2

thomasvanholder avatar Aug 05 '22 08:08 thomasvanholder

Yeah I can reproduce - looks like the value is not being type cast. I will open a PR for this.

andrewn617 avatar Aug 05 '22 13:08 andrewn617