Rails 4 中的虚拟属性
Virtual Attribute in Rails 4
我有一个产品型号,我需要在 _form 视图中写入管理员要插入的产品编号。
我还有另一个 table 供应(产品数量)
所以在我的产品 table 中我没有属性 quantity ,但我只有 supply_id
(链接我的两个 table 产品和供应)
由于我的产品中没有数量table,我在产品上使用了虚拟属性。
我不得不更改新产品和编辑产品的视图
因为在新的中我想要字段数量但在编辑中我不想要(因为我使用另一个视图来做到这一点)
所以,我删除了部分 _form 并创建了单独的视图。
此外,我必须在产品控制器中设置,如果我想更新产品,我必须调用 set_quantity 回调,因为我必须插入一个 "fake" 值来填充 params[:product][:quantity]
.这是因为我在产品模型中的数量虚拟字段上将验证存在设置为 true。我想知道,如果所有这个故事都是正确的(它有效,但我想要一个关于这个故事的编程设计的建议。因为我不喜欢这样的事实,即当我有更新产品)
控制器:
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/setters,而不是使用 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
我有一个产品型号,我需要在 _form 视图中写入管理员要插入的产品编号。
我还有另一个 table 供应(产品数量)
所以在我的产品 table 中我没有属性 quantity ,但我只有 supply_id
(链接我的两个 table 产品和供应)
由于我的产品中没有数量table,我在产品上使用了虚拟属性。
我不得不更改新产品和编辑产品的视图
因为在新的中我想要字段数量但在编辑中我不想要(因为我使用另一个视图来做到这一点)
所以,我删除了部分 _form 并创建了单独的视图。
此外,我必须在产品控制器中设置,如果我想更新产品,我必须调用 set_quantity 回调,因为我必须插入一个 "fake" 值来填充 params[:product][:quantity]
.这是因为我在产品模型中的数量虚拟字段上将验证存在设置为 true。我想知道,如果所有这个故事都是正确的(它有效,但我想要一个关于这个故事的编程设计的建议。因为我不喜欢这样的事实,即当我有更新产品)
控制器:
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/setters,而不是使用 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