2017-03-06 31 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

相關問題