Значения по умолчанию для полей модели в форме Ruby on Rails - PullRequest
4 голосов
/ 19 января 2011

У меня есть Model, в котором есть поля username, data, tags, date, votes.У меня есть форма, использующая form_for, которая создает новый элемент и помещает его в базу данных.Однако, как вы можете догадаться, я хочу, чтобы поле голосования равнялось 0, а поле даты равнялось текущей дате, когда оно помещается в базу данных.Как и где мне установить / применить эти значения к элементу?

Я могу заставить его работать со скрытыми полями в форме, но это сопряжено с очевидными проблемами (кто-то может установить для поля votes массивнуюномер).

Ответы [ 5 ]

10 голосов
/ 19 января 2011

Просто используйте значение по умолчанию;ноль, для голосов в БД используйте автоматические метки времени (created_at) вместо date, и в форме есть поля только для параметров, которые вы будете устанавливать.Не забудьте защитить чувствительные атрибуты.

class CreateModels < ActiveRecord::Migration
  def up
    create_table :models do |t|
      t.string :username
      t.text :data
      t.string :tags
      t.integer :votes, :default => 0

      t.timestamps # this will give you two automatic fields: created_at and updated_at
    end
  end
  …
end

class Model < ActiveRecord::Base
  attr_protected :votes #so that it cannot be set by mass assignment
  …
end
5 голосов
/ 20 ноября 2011

Я могу подтвердить, что подход с ограничениями БД является одним из лучших. Но это не всегда возможно использовать. Предположим, что существует единственное наследование таблицы и требуется другое значение по умолчанию для дочерней модели. Чем я рекомендую поместить это в модель. Позвольте мне привести пример:

class ChildModel < Model
  after_initialize :set_defaults
  private
  def set_defaults
    self.allowed_votes_per_person = 10 if self.new_record?
  end 
end

При использовании обратного вызова: after_initialize нет необходимости создавать и не забывать вызывать методы, подобные new_default, и так далее. Он устанавливает требуемые значения по умолчанию, но остается ненавязчивым с точки зрения интерфейса при вызове ChildModel.new

3 голосов
/ 19 января 2011

Один простой способ - установить значения по умолчанию для действия create на контроллере.

@model = Model.new(params[:model])
@model.votes = 1
@model.date = Time.now
@model.save

Другой способ, более понятный, - создать метод в модели.

class Model

def new_default(model)
  model = Model.new(model)
  model.votes = 1
  model.date = Time.now
end

Итак, в вашем контроллере у вас будет:

@model = Model.new_default(params[:model])

if @model.save
   render something
else
   render something_else
end
1 голос
/ 19 января 2011

Вот скринкаст по защите атрибутов: http://railscasts.com/episodes/26-hackers-love-mass-assignment

Модели Rails поставляются с автоматической отметкой времени по умолчанию, поля selected_at и updated_at являются именами атрибутов. Вам не нужно беспокоиться об их установке, это поможет вам.

0 голосов
/ 23 января 2012

У меня пока нет права комментировать другие ответы, но у меня есть связанный вопрос с Нерианом, поэтому я публикую это.Я использую код типа

before_create : create_rest
def create_rest
  15.times do
    self.players.build({:name => Rnlist.order("rand()").first.raname,
                        :cost => 140+rand(40),
                        :coop => rand(3)})
  end
end

в модели user.rb.Этот код прекрасно работает и создает 15 игроков с разными именами и т. Д. Однако, если я пытаюсь поместить атрибуты в модель игрока так, как вы предлагаете (используя метод create в Players_controller), метод self.players.build создает15 игроков с пустыми атрибутами без каких-либо ошибок.Я думал, что попытка кода с новым методом вместо create в Players_controller может решить эту проблему, но результат тот же.Может ли метод self.players.build вызвать проблему?Я проверил Ruby API для others.build (), а также блог Vinhboy.com , но не смог решить эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...