2017-03-06 27 views
1

我是一名Rails新手,尽管我已经构建了一个包含erb文件,ruby和postgres的应用程序,但我发现很难找出如何编写类方法的语法,特别是如果你想做的不仅仅是CRUD。如何使用has_one创建关联的记录和修改数据

我有两个表格:material & material_costs 材料has_one material_cost和material_cost属于材料。

Material模型的每个新条目都应该自动填充material_costs的一个条目。使用材料中的三个字段,我需要修改将创建新材料成本记录的数据。

我花了数小时试图找到build_with函数的正确语法。不是那么容易,即使使用rails文档。

到目前为止的代码:

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列?

回答

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。

至于你的迁移,是的,如果你没有指定一个,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 

被警告,这将删除所有现有数据在你的数据库。

+0

感谢@eiko,看上去很不错。麻烦播种测试它。应该很快就会好的! – godhar

+0

@godhar我编辑了我的答案,包括有关您的移民困境的评论。 – eiko

2

那么你是在正确的轨道,但你需要改变一些东西有点

  1. has_one必须是单数
  2. belongs_to必须是单数
  3. 您可以使用after_create回调创建相关material_cost对于Material
  4. 您不需要@material = current_material,因为您可以将其称为self
  5. 如果您正在使用build您需要保存的实例或使用create
  6. 使用CONSTANT的价值观像0.06265148760.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 
+0

谢谢@Deepak ...看起来像正确的语法,现在我无法播种Material表,以查看它是否创建了material_costs的记录。我得到:MaterialCost的未知属性material_id。我认为rails格式化了所有关系的ID? – godhar

+0

@godhar对于响应缓慢感到抱歉。你有没有为你的数据库生成任何迁移?如果是这样,你可以发布你的迁移文件的材料和MaterialCost? – eiko

+0

是的我有一系列的迁移。我关闭了我的机器和psql服务器,然后启动它并重新创建表和迁移。所有这些错误都发生了。 – godhar

相关问题