2015-04-10 2 views
0

Я новичок в разработке рельсов и приложений, поэтому прошу прощения.Rails model if statement

У меня есть модель под названием продукт, который имеет следующую схему():

t.string "name" 
    t.integer "cost" 
    t.boolean "in_stock" 
    t.datetime "sold_date" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "quantity" 

Я хочу in_stock вернуть истину, если количество больше 1, в противном случае ложь. Я написал следующий код в файле product.rb, но он ничего не делает, когда я ввожу количество продуктов через консоль. Я не уверен, что мне нужно связать столбцы базы данных (in_stock и количество) с оператором if или нет. Или даже если это правильный путь. Я был бы благодарен за любые предложения. Благодаря!

class Product < ActiveRecord::Base 
belongs_to :company 

def in_stock 
    if quantity >= 1 
     in_stock true 
    else 
     in_stock false 
end 
+0

Вы должны использовать * обратные вызовы *. –

+0

@ bsvin33t Почему? Я не знал о –

+0

Если они неправильно используются, они создают хотя бы для обработки ситуаций. Например: отправка сообщений электронной почты в обратные вызовы, ** плохая идея **. Анекдот, который я слышал в одном из собраний, имел что-то подобное, и когда они перенаправляли базы данных и выполняли рейк-задачу, затопили своих пользователей тонны текста и электронных писем. – bsvin33t

ответ

1

Хранение обоих quantity и in_stock в базе данных может привести к несогласованности данных:

+----+----------+----------+ 
| id | in_stock | quantity | 
+----+----------+----------+ 
| 1 |  true |  0 | 
| 2 | false |  15 | 
+----+----------+----------+ 

Я бы вычислить in_stock на основе количества и использовать дополнительный scope для запросов:

class Product < ActiveRecord::Base 
    scope :in_stock, -> { where('quantity > 0') } 

    def in_stock? 
    quantity > 0 
    end 
end 

Далее , вы должны убедиться, что значение quantity имеет значение по умолчанию 0 и что оно не может быть NULL.

+0

это здорово! Как использовать область, отличную от только def in_stock? thx – Arkane55

+0

@ Arkane55 область применения используется для запросов, например. 'Product.in_stock.where (...)', а метод экземпляра используется при работе с экземплярами, например. 'if @ product.in_stock? ... ' – Stefan

0

Это не возвращает истину, вы, вероятно, случайно написали in_stock true. Попробуйте изменить его на это:

def in_stock? 
    quantity > 0 
end 

Редактировать: Также похоже, что вы хотите установить переменную in_stock. Вы можете попробовать что-то вроде:

class Product < ActiveRecord::Base 
    after_update :update_in_stock 

    def update_in_stock 
    if quantity > 0 
     in_stock = true 
    end 
    end 

end 

Edit: Решение bsvin33t также работает, но если вы делаете эту модель для чего-то, что зависит от логического значения присутствующей (как предусмотрено в исходном коде), то я бы придерживаться с вышеуказанным кодом. Если нет, используйте метод, который я предоставляю в верхней части этого сообщения, и просто удалите поле БД.

+0

@ user2752843 Я пробовал ваше решение, но я все еще получаю in_stock: null, когда я обновил количество. Я что-то упускаю? Благодарю. – Arkane55

+0

@njny использует обратный вызов 'before_validate' и использует' update_attributes (in_stock: true) 'в методе обратного вызова. @ Arkane55 – bsvin33t

1

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

метод должен быть

def in_stock? 
    quantity > 0 
end 

Следуйте конвенции рубин. И, если его можно вычислить, не храните его. Вам придется иметь дело с проблемами устаревших данных. И вообще, как правило, старайтесь избегать обратных вызовов как можно больше. Если вам нужно использовать его, убедитесь, что он изменяет состояние self, а не какой-либо другой объект.