Search code examples
ruby-on-railsrubyactiverecord

How to pass non-column argument to ActiveRecord new?


Let's assume I have a MySQL table like below.

create table users (
    id int,
    full_name varchar(30)
);

and I want to create a model with User.new(id: 1, first_name: "Michael", last_name: "Jackson") but ActiveRecord raises unknown attribute 'first_name' for User..

Userclass is Just an example, I want it to be an meta class(like Employee < User). So, creating build method is not the way really I want.

class User
  attr_accessor :first_name, :last_name
  
  before_create :create_full_name

  def create_full_name
    self.full_name = "#{first_name} #{last_name}"
  end
end 

user = User(id: 1)
user.first_name = "Michael"
user.last_name = "Jackson"

Is pretty close, but this needs an additional assignment from outside. I don't want this redundancy.

Is there any way to this?


Solution

  • You can use the initialize method to set the attributes. You can also use the send method to set the attributes. For example:

    class User
      attr_accessor :first_name, :last_name
    
      def initialize(attributes = {})
        attributes.each do |name, value|
          send("#{name}=", value)
        end
      end
    end
    
    user = User.new(id: 1, first_name: "Michael", last_name: "Jackson")
    p user.first_name
    p user.last_name
    
    # Output:
    # "Michael"
    # "Jackson"