Arkane55
Arkane55

Reputation: 17

Rails model if statement

I'm new to rails and app development so forgive any mistakes.

I've got a model called Product which has the following (schema):

    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"

I want the in_stock to return true if the quantity is greater than 1, otherwise false. I wrote the following code in the product.rb file but it doesn't seem do anything when I enter the product quantities through the console. I'm not sure if I have to link the database columns (in_stock and quantity) to the if statement or not. Or if even this is the right way to go about things. I'd be grateful for any suggestions. Thanks!

class Product < ActiveRecord::Base
belongs_to :company

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

Upvotes: 0

Views: 2570

Answers (3)

Stefan
Stefan

Reputation: 114178

Storing both, quantity and in_stock in your database can result in inconsistent data:

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

I'd compute in_stock based on quantity and use an additional scope for queries:

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

  def in_stock?
    quantity > 0
  end
end

Furthermore, you should ensure that quantity has a default value of 0 and that it cannot be NULL.

Upvotes: 1

njny
njny

Reputation: 569

That's not returning true, you probably accidentally wrote in_stock true. Try changing it to this:

def in_stock?
    quantity > 0
end 

Edit: Also it looks like you want to actually set the in_stock variable. You could try something like:

class Product < ActiveRecord::Base
  after_update :update_in_stock

  def update_in_stock
    if quantity > 0 
        in_stock = true
    end
  end

end

Edit: bsvin33t's solution also works, however if you are making this model for something that depends on the boolean being present (as you provided in your original code), then I would stick with the above code. If not, then use the method I provide at the top of this post and just remove your DB field.

Upvotes: 0

bsvin33t
bsvin33t

Reputation: 638

For starters, you don't need the boolean field in_stock to be present in the database, as it can be calculated.

the method has to be

def in_stock?
  quantity > 0
end

Follow the ruby conventions. And, if it can be calculated, don't store it. You will have to deal with issues of stale data. And generally, as a rule of thumb, try to avoid callbacks as much as possible. If you have to use it, make sure that it is modifying the state of the self and not some other object.

Upvotes: 1

Related Questions