How to initialize an ActiveRecord with values in Rails?

前端 未结 5 1687
情话喂你
情话喂你 2020-12-17 08:35

In plain java I\'d use:

public User(String name, String email) {
  this.name = name;
  this.email = f(email);
  this.admin = false;
}

相关标签:
5条回答
  • 2020-12-17 09:03

    I was searching for something similar this morning. While setting a default value in the database will obviously work, it seems to break with Rails' convention of having data integrity (and therefore default values?) handled by the application.

    I stumbled across this post. As you might not want to save the record to the database immediately, I think the best way is to overwrite the initialize method with a call to write_attribute().

    def initialize
      super
      write_attribute(name, "John Doe")
      write_attribute(email,  f(email))
      write_attribute(admin, false)
    end
    
    0 讨论(0)
  • 2020-12-17 09:04

    This will work in rails 4.

    def initialize(params)
        super
        params[:name] = params[:name] + "xyz" 
        write_attribute(:name, params[:name]) 
        write_attribute(:some_other_field, "stuff")
        write_attribute(:email, params[:email])
        write_attribute(:admin, false)
    end
    
    0 讨论(0)
  • 2020-12-17 09:05

    One solution that I like is via scopes:

    class User ...
       scope :admins, where(admin: true)
    

    Then you can do both: create new User in the admin status(i.e. with admin==true) via User.admins.new(...) and also fetch all your admins in the same way User.admins.

    You can make few scopes and use few of them as templates for creating/searching. Also you can use default_scope with the same meaning, but without a name as it is applied by default.

    0 讨论(0)
  • 2020-12-17 09:08

    According to Rails Guides the best way to do this is with the after_initialize. Because with the initialize we have to declare the super, so it is best to use the callback.

    0 讨论(0)
  • 2020-12-17 09:19

    Your default values should be defined in your Schema when they will apply to ALL records. So

    def change
      creates_table :posts do |t|
        t.boolean :published, default: false
        t.string :title
        t.text :content
        t.references :author
        t.timestamps
      end
    end
    

    Here, every new Post will have false for published. If you want default values at the object level, it's best to use Factory style implementations:

    User.build_admin(params)
    
    def self.build_admin(params)
      user = User.new(params)
      user.admin = true
      user
    end
    
    0 讨论(0)
提交回复
热议问题