我是一个铁杆新手,虽然我已经构建了一个带有erb文件,ruby和postgres的应用程序,但我发现很难找到如何编写类方法的语法,特别是如果你想做的不仅仅是CRUD 。
我有两张桌子:材料& material_costs 材料has_one material_cost和material_cost属于Material。
Material模型的每个新条目都应自动将一个条目填充到material_costs。使用Material中的三个字段,我需要修改将创建新材料成本记录的数据。
我花了好几个小时试图找到build_with函数的正确语法。即使使用rails docs也不是那么容易。
到目前为止代码:
class Material < ApplicationRecord
has_and_belongs_to_many :job_entries
has_one :material_costs, :material_charges, :dependent => :destroy
@material = current_material
@material_cost = @material.build_material_costs(
:cost_a4 => ((@material.cost_per_sqm + @material.ink_per_sqm) * 0.0626514876)
:cost_a3 => ((@material.cost_per_sqm + @material.ink_per_sqm) * 0.124548139)
end
class MaterialCost < ApplicationRecord
belongs_to :materials
end
移植
class CreateMaterials < ActiveRecord::Migration[5.0]
def change
create_table :materials do |t|
t.string :product_name, :guk_name
t.integer :roll_width_in, :roll_length_m, :factor, :rounded_sale_price
t.float :list_price, :cost_per_sqm, :ink_per_sqm, :supplier_discount, :sell_per_sqm
t.timestamps
end
end
end
我是否在正确的轨道上?任何人都知道有关构建用于基本查询和修改数据的类模型方法的用户友好指南吗?谢谢,godhar
class CreateMaterials < ActiveRecord::Migration[5.0]
def change
create_table :materials do |t|
t.string :product_name, :guk_name
t.integer :roll_width_in, :roll_length_m, :factor, :rounded_sale_price
t.float :list_price, :cost_per_sqm, :ink_per_sqm, :supplier_discount, :sell_per_sqm
t.timestamps
end
end
end
class CreateMaterialCosts < ActiveRecord::Migration[5.0]
def change
create_table :material_costs do |t|
t.float :cost_a4, :cost_a3, :cost_a2, :cost_a1, :cost_b0, :cost_b1, :cost_b2
t.float :cost_b3, :cost_b4
t.timestamps
end
end
end
关闭我的机器和psql服务器后,重新启动并重新启动服务器,重新创建数据库,然后最终迁移我的所有迁移,我在错误地狱。如果有人放弃了表格,那么惯例是什么?我应该编辑迁移文件,以便重命名列和所有这些编辑迁移都不会运行吗?即我是否有机会从头开始,或者我是否也必须迁移我的所有更改?另外,我们是否要添加id列?我认为通过关系Rails为我们设置了ID,我相信我会在某处读到它?我们在何时何地添加id列?
答案 0 :(得分:2)
试试这个:
class Material < ApplicationRecord
has_and_belongs_to_many :job_entries
has_one :material_cost, :material_charge, :dependent => :destroy
after_create do
self.create_material_cost(
cost_a4: (self.cost_per_sqm + self.ink_per_sqm) * 0.0626514876),
cost_a3: (self.cost_per_sqm + self.ink_per_sqm) * 0.124548139)
)
end
end
class MaterialCost < ApplicationRecord
belongs_to :materials
end
after_create
指定在创建每个材料后自动运行的代码块。 create_material_cost
是使用has_one关系时生成的辅助方法。它允许您创建一个与给定材料自动关联的MaterialCost。
对于您的迁移,yes rails会在您未指定迁移时自动添加id列。默认名称为:id。 不自动添加的导轨是将您的MaterialCosts链接到其父材质的外键列。您可以通过创建新迁移来添加它:
class AddMaterialIDToMaterialCosts < ActiveRecord::Migration[5.0]
def change
add_column :material_costs, :material_id, :integer
end
end
要重置数据库并重新加载迁移,请运行:
rails db:drop db:create db:migrate db:seed
请注意,这将删除数据库中的所有现有数据。
答案 1 :(得分:2)
嗯,你走在正确的轨道上,但你需要改变一些事情
has_one
必须是单数belongs_to
必须是单数after_create
回调为material_cost
Material
@material = current_material
,因为您可以将其称为self
build
,则需要保存实例或使用create
CONSTANT
作为0.0626514876
和0.124548139
等值,因此如果您需要更改它们,则无需在项目范围内搜索它们。因此,在修复这些内容之后,代码将是
<强> material.rb 强>
class Material < ApplicationRecord
has_and_belongs_to_many :job_entries
has_one :material_cost, :material_charge, dependent: :destroy
after_create :set_material_cost
A3_FACTOR = 0.124548139
A4_FACTOR = 0.0626514876
private
def set_material_cost
@material_cost = self.create_material_cost(
cost_a4: (cost_per_sqm + ink_per_sqm) * A4_FACTOR,
cost_a3: (cost_per_sqm + ink_per_sqm) * A3_FACTOR
)
end
end
<强> material_cost.rb 强>
class MaterialCost < ApplicationRecord
belongs_to :material
end