web-dev-qa-db-fra.com

Valeurs par défaut pour les modèles en rails

Est-il préférable de définir la valeur par défaut dans la migration ou dans le rappel? Il est difficile de supprimer (ou de définir une autre) valeur par défaut dans la migration, mais dans le modèle, modifiez un code supplémentaire.

12
Denis Papushaev

La définition de valeurs par défaut dans votre migration présente également certains inconvénients. Cela ne fonctionnera pas lorsque vous appelez simplement Model.new.

Je préfère écrire un after_initialize callback, ce qui me permet de définir les attributs par défaut:

class Model < ActiveRecord::Base
  after_initialize :set_defaults, unless: :persisted?
  # The set_defaults will only work if the object is new

  def set_defaults
    self.attribute  ||= 'some value'
    self.bool_field = true if self.bool_field.nil?
  end
end 
26
Sharvy Ahmed

Dans Rails 5, les attributs API permettent de spécifier des valeurs par défaut. La syntaxe est simple et vous permet de modifier une valeur par défaut sans migration.

# db/schema.rb
create_table :store_listings, force: true do |t|
  t.string :my_string, default: "original default"
end

# app/models/store_listing.rb
class StoreListing < ActiveRecord::Base
  attribute :my_string, :string, default: "new default"
end
11
w_hile

En règle générale, sur le serveur, appliquez des contraintes aux modèles et à la base de données. C'est comme la validation JS et ne pas valider dans le backend (PHP, ROR, etc.). Quelqu'un peut modifier votre JS pour passer la validation et, comme vous ne l'avez pas validé sur le backend, votre site peut être compromis. Par conséquent, validez toujours des deux côtés, du moins si votre serveur d’applications est compromis, le serveur de base de données peut se défendre.

1
Abraham

Piggy-backing sur @ w-hile answer - ce qui est une excellente solution, à moins que vous souhaitiez effectuer un "paramétrage" -

J'en avais marre de polluer mes modèles avec un tas de chroniques consacrées aux réglages, alors j'ai écrit Setsy .

class User < ApplicationRecord

  include ::Setsy::DSL

  # each setting can be a hash, like posts_limit, or just a value
  DEFAULT_SETTINGS = {
    posts_limit: { value: 10 },
    favorite_color: 'blue'
  }.freeze

  setsy :settings, column: :settings_data, defaults: DEFAULT_SETTINGS do |conf|
    conf.reader :posts_limit_and_color do
      "posts limit is #{posts_limit} and color is #{favorite_color}"
    end
  end
end

Et tu peux,

user = User.first
user.settings # {posts_limit: 10, favorite_color: 'blue'}
user.settings.posts_limit # 10
user.settings.posts_limit.default? # true 
user.assign_attributes(settings_data: { posts_limit: 15, favorite_color: 'blue' })
user.settings.posts_limit.default? # false 
user.settings.posts_limit.default # 10 
0
Josh Brody