简体   繁体   English

Rails中的虚拟属性4

[英]Virtual Attribute in Rails 4

I have a model of product and I need to write in the _form view , the number of the product that an admin wants to insert. 我有一个产品模型,我需要在_form视图中写入,管理员想要插入的产品的数量。 I have another table with the Supply (number of product) so in my product table I don't have the attribute quantity , but I have just the supply_id (that links my two tables of product and supply) 我有另一个包含Supply(产品数量)的表,所以在我的产品表中我没有属性数量,但我只有supply_id (链接我的两个产品和供应表)

Since I don't have the quantity in my product table, I used a virtual attribute on Product. 由于我的产品表中没有数量,因此我在Product上使用了虚拟属性。

I had to change the view of the new and edit product cause in the new I want the field quantity but in the edit I don't want (cause I use another view to do this) So, I deleted the partial _form and created separate view. 我不得不改变新的视图和编辑产品的原因在新的我希望字段数量但在编辑中我不想要(因为我使用另一个视图来做这个)所以,我删除了部分_form并创建了单独的视图。 Also, I had to set in the controller of products that if I want to update a product, i have to call a set_quantity callback, cause I have to insert a "fake" value to fill the params[:product][:quantity] . 另外,我必须在产品的控制器中设置如果我想更新产品,我必须调用set_quantity回调,因为我必须插入一个“假”值来填充params[:product][:quantity] This , because I setted the validation presence true ,on the quantity virtual field in the product model. 这是因为我在产品模型中的数量虚拟字段上设置了验证状态为true。 I want to know , if all this story is right (it works , but I want a suggestion about the programming design of this story. Cause I don't like the fact that I give a fake value to fill the quantity field when I have to update a product) 我想知道,如果所有这些故事都是正确的(它有效,但我想要一个关于这个故事的编程设计的建议。因为我不喜欢这样一个事实,即当我有一个假值来填充数量字段时更新产品)

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

Model: 模型:

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

Can you say me if there is a better way to fill the param[:product][:quantity] in the case of the update action? 如果在更新操作的情况下有更好的方法来填充param[:product][:quantity] ,你能说我吗? Cause i don't like the fact that i give it the value of 2. Thank you. 因为我不喜欢我给它的值2的事实。谢谢。

Instead of using attr_accessor you could create custom getter/setters on your product model. 您可以在产品型号上创建自定义getter / setter,而不是使用attr_accessor Note that these are not backed by an regular instance attribute. 请注意,这些不受常规实例属性的支持。

Also you can add a validation on the supply association instead of your virtual attribute. 您还可以supply关联上添加验证,而不是虚拟属性。

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

In Ruby assignment is actually done by message passing: 在Ruby中,赋值实际上是通过消息传递完成的:

product.quantita = 1

Will call product#quantita= , with 1 as the argument. 将调用product#quantita= ,以1为参数。

Another alternative is to use nested attributes for the supply. 另一种方法是使用嵌套属性

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

This means that Product accepts supply_attributes - a hash of attributes. 这意味着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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM