ruby-on-rails - Rails 4 中的虚拟属性

标签 ruby-on-rails ruby ruby-on-rails-4 virtual-attribute

我有一个产品模型,我需要在 _form View 中写入管理员想要插入的产品编号。 我有另一张供应表(产品数量) 所以在我的产品表中我没有属性 quantity ,但我只有 supply_id (链接我的产品和供应的两个表)

由于我的产品表中没有数量,所以我在产品上使用了虚拟属性。

我不得不更改新产品和编辑产品的 View 因为在新的中我想要字段数量但在编辑中我不想要(因为我使用另一个 View 来做到这一点) 所以,我删除了部分 _form 并创建了单独的 View 。 此外,我必须在产品 Controller 中设置,如果我想更新产品,我必须调用 set_quantity 回调,因为我必须插入一个“假”值来填充 params[:product][ :数量]。这是因为我在产品模型中的数量虚拟字段上将验证存在设置为 true。我想知道,如果所有这个故事都是正确的(它有效,但我想要一个关于这个故事的编程设计的建议。因为我不喜欢这样的事实,即当我有更新产品)

Controller :

class ProductsController < ApplicationController
    include SavePicture 
    before_action :set_product, only: [:show, :edit, :update, :destroy]
    before_action :set_quantita, only: [:update]
    ....

    def set_quantita
       params[:product][:quantita]=2  #fake value for the update action
    end
    ....
end

型号:

class Product < ActiveRecord::Base
    belongs_to :supply ,dependent: :destroy
    attr_accessor :quantita
    validates :quantita, presence:true
end

如果有更好的方法来填充更新操作的param[:product][:quantity],您能告诉我吗?因为我不喜欢我给它的值 2。谢谢。

最佳答案

您可以在产品模型上创建自定义 getter/setter,而不是使用 attr_accessor。请注意,这些不受常规实例属性的支持。

您也可以 add a validation on the supply association而不是您的虚拟属性。

class Product < ActiveRecord::Base
  belongs_to :supply ,dependent: :destroy
  validates_associated :supply, presence:true

  # getter method
  def quantita
    supply
  end

  def quantita=(val)
    if supply
      supply.update_attributes(value: val)
    else
      supply = Supply.create(value: val)
    end
  end
end

在 Ruby 中,赋值实际上是通过消息传递完成的:

product.quantita = 1

将以 1 作为参数调用 product#quantita=

另一种选择是使用 nested attributes用于供应。

class Product < ActiveRecord::Base
  belongs_to :supply ,dependent: :destroy
  validates_associated :supply, presence:true
  accepts_nested_attributes_for :supply
end

这意味着 Product 接受 supply_attributes - 属性的散列。

class ProductsController < ApplicationController

  #...
  before_action :set_product, only: [:show, :edit, :update, :destroy]

  def create
    # will create both a Product and Supply
    @product = Product.create(product_params)
  end

  def update
    # will update both Product and Supply
    @product.update(product_params)
  end

  private

  def product_params
    # Remember to whitelist the nested parameters!
    params.require(:product)
          .allow(:foo, supply_attributes: [:foo, :bar])
  end
  # ...
end

关于ruby-on-rails - Rails 4 中的虚拟属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30914780/

相关文章:

mysql - 我们真的需要在删除表之前删除外键吗?

mysql - .where 中两个日期之间的差异

ruby-on-rails - irb 和 rails 控制台为 [].blank 显示不同的结果?

ruby-on-rails - 获取Rails中公共(public)文件夹内文件的绝对路径

ruby-on-rails - Ruby on Rails 带有用户身份验证的curl POST 请求

Ruby on Rails : Delayed Job is it possible to execute one job then stop?

ruby-on-rails - Rails 4.x 和 app/controllers/concerns 中的子文件夹

mysql - rails db:migrate rails 中止! Mysql2::错误:用户 'root' @'localhost' 的访问被拒绝(使用密码:是)

ruby-on-rails - Stripe Live 可发布 API key 不正确

ruby-on-rails - 当使用 "find_all_by"时,为什么使用 :order => :title rather than :order => title