【问题标题】:Rails model if statementRails 模型 if 语句
【发布时间】:2015-04-10 19:50:54
【问题描述】:

我是 Rails 和应用开发新手,如有错误请见谅。

我有一个名为 Product 的模型,它具有以下(模式):

    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"

如果数量大于 1,我希望 in_stock 返回 true,否则返回 false。我在 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 

【问题讨论】:

  • 你必须使用回调
  • @bsvin33t 为什么?我不知道
  • 如果被滥用,他们会创造虽然来处理情况。例如:在回调中发送电子邮件,坏主意。我在一次聚会中听到的轶事,有类似的事情,当他们迁移数据库并运行 rake 任务时,他们的用户充斥着大量的文本和电子邮件。
  • @bsvin33t 我觉得如果使用得当,回调是一个强大的工具。在回调中发送电子邮件可能确实是个坏主意,但仍然可以添加检查并小心。此外,如果他想将 in_stock 布尔值保存在 DB 中,他可能需要使用回调。他们并不总是邪恶的:)

标签: ruby-on-rails ruby if-statement model


【解决方案1】:

在您的数据库中同时存储quantityin_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

【讨论】:

  • 太棒了!使用范围与仅定义 in_stock 有何不同?谢谢
  • @Arkane55 范围用于查询,例如Product.in_stock.where(...),并且在处理实例时使用实例方法,例如if @product.in_stock? ...
【解决方案2】:

对于初学者,您不需要布尔字段 in_stock 存在于数据库中,因为它可以计算出来。

方法必须是

def in_stock?
  quantity > 0
end

遵循 ruby​​ 约定。并且,如果可以计算,请不要存储它。您将不得不处理过时数据的问题。一般来说,根据经验,尽量避免回调。如果必须使用它,请确保它正在修改 self 的状态,而不是其他对象。

【讨论】:

    【解决方案3】:

    这不是真的,你可能不小心写了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
    

    编辑:bsvin33t 的解决方案也有效,但是如果您正在为依赖于存在的布尔值(如您在原始代码中提供的)的东西制作此模型,那么我会坚持使用上面的代码。如果没有,请使用我在本文顶部提供的方法,然后删除您的 DB 字段。

    【讨论】:

    • @user2752843 我尝试了您的解决方案,但当我更新数量时,我仍然收到 in_stock: null 。我错过了什么吗?谢谢。
    • @njny 使用before_validate 回调并在回调方法中使用update_attributes(in_stock: true)。 @Arkane55
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 2022-01-22
    • 2021-09-19
    相关资源
    最近更新 更多