簡體   English   中英

無法通過關聯更新has_many中的聯接模型額外屬性-Rails

[英]Having trouble in updating join model extra attributes in has_many through association - Rails

我仍然是Rails的學習者,並且正在制作Google Adwords模擬游戲以進行培訓。 游戲里面的(我只能說明這個問題的相關部分),我有三個型號, 廣告組 (在我的代碼稱為KeywordAdgroup), 關鍵字,AdgroupKeyword,同時又有中有一個game_id博弈模型。

這三種模型之間的關系是has_many through:關聯,即Adgroup通過AdgroupKeyword具有許多關鍵字,而Adword通過AdgroupKeyword具有許多關鍵字。

現在,我想采用一種邏輯,即每個關鍵字只能添加到特定游戲的單個廣告組中。 因此,我在聯接模型中添加了一個額外的屬性game_id -AdgroupKeyword,並在模型中采用了validates_uniqueness_of :keyword_id, scope: :game_id

但是,我發現使用類似的代碼,我可以使用.save方法驗證Create中的唯一性,但無法使用.update(params)方法驗證Update中的唯一性。

主要問題在於,使用createupdate類似的代碼,創建者可以save game_id save到聯接模型(AdgroupKeyword)中,而update(params)沒有將game_id保存到聯接模型中(在控制台中) ,我可以看到update沒有在記錄中插入game_id。

它將變成類似於game_id: nil

#<AdgroupKeyword id: 180, keyword_id: 9, created_at: "2016-12-04 11:12:00", updated_at: "2016-12-04 11:12:00", keyword_adgroup_id: 77, game_id: nil>

但是save方法確實插入了game_id,當使用save方法插入時game_id並非為nil。 就像是

#<AdgroupKeyword id: 174, keyword_id: 10, created_at: "2016-12-04 10:23:50", updated_at: "2016-12-04 10:23:50", keyword_adgroup_id: 77, game_id: 3>

以下是我的代碼:

keyword_adgroup.rb (廣告組的模型)

class KeywordAdgroup < ApplicationRecord
  belongs_to :keyword_campaign

  has_many :adgroup_keywords, inverse_of: :keyword_adgroup, dependent: :destroy
  has_many :keywords, through: :adgroup_keywords, source: :keyword
  accepts_nested_attributes_for :adgroup_keywords, allow_destroy: true

  ...

  accepts_nested_attributes_for :keywords

  ...

  ...
end

keyword.rb

class Keyword < ApplicationRecord
  ...

  ...

  has_many :keyword_adgroups, through: :adgroup_keywords
  has_many :adgroup_keywords

  ...
end

adgroup_keyword.rb聯接模型)

class AdgroupKeyword < ApplicationRecord
  belongs_to :keyword_adgroup
  belongs_to :keyword

  validates_uniqueness_of :keyword_id, scope: :game_id

end

關系主要建立在Adgroup控制器中。

adgroups_controller.rb

class Adwords::AdgroupsController < AdwordsController

  def index
    ...
  end

  def new
    @adgroup = KeywordAdgroup.new
  end

  def create
    @campaign = current_user.game.keyword_campaigns.find(params[:keyword_campaign_id])
    @adgroup = @campaign.keyword_adgroups.build(adgroup_params)
    @adgroup.game_id = @campaign.game_id
    @adgroup.adgroup_keywords.each do |join|
      join.game_id = @adgroup.game_id    
    end

    if @adgroup.save
      redirect_to new_adwords_ad_path(keyword_adgroup_id: @adgroup.id)
    else
      render :new
    end
  end

  def edit
    @adgroup = KeywordAdgroup.find(params[:id])
  end

  def update
    @adgroup = KeywordAdgroup.find(params[:id])
    @campaign = @adgroup.keyword_campaign
    @adgroup.game_id = @campaign.game_id
    @joins = @adgroup.adgroup_keywords
    @joins.each do |join|
      join.game_id = @adgroup.game_id  
    end 
    if @adgroup.update(adgroup_params)

      redirect_to adwords_adgroups_path, notice: "Adgroup updated"
    else
      render :edit
    end
  end

  ...

  private
  def adgroup_params
    params.require(:keyword_adgroup).permit(:name, :activate, :bid, keyword_ids: [], adgroup_keywords_attributes: [:game_id])
  end

end

在同一個游戲中,無論在哪個廣告組中選擇重復的關鍵字,都可以在“創建”中進行回滾; 在“更新”中,它將僅使用game_id: nil更新記錄。

僅供參考,我正在使用Ruby 2.3.0,Rails 5.0.0,並使用simpleform創建和更新廣告組。

我知道這有點混亂,對此感到抱歉,並感謝您閱讀我的話。 感謝任何建議。 已經花了幾個小時來修復它,但是在采用許多不同的方法后卻真的沒有希望。 認為這是我尚未弄清楚的一些概念性問題。


更新信息

在檢查控制台時,在“創建”方法中,它將出現:

  AdgroupKeyword Exists (0.4ms)  SELECT  1 AS one FROM "adgroup_keywords" WHERE "adgroup_keywords"."keyword_id" = ? AND "adgroup_keywords"."game_id" = ? LIMIT ?  [["keyword_id", 14], ["game_id", 3], ["LIMIT", 1]]
  Keyword Exists (0.3ms)  SELECT  1 AS one FROM "keywords" WHERE "keywords"."keyword" = ? AND ("keywords"."id" != ?) LIMIT ?  [["keyword", "Japan local trip"], ["id", 14], ["LIMIT", 1]]
  KeywordAdgroup Exists (0.2ms)  SELECT  1 AS one FROM "keyword_adgroups" WHERE "keyword_adgroups"."name" = ? AND "keyword_adgroups"."keyword_campaign_id" = ? LIMIT ?  [["name", "3"], ["keyword_campaign_id", 36], ["LIMIT", 1]]
  SQL (2.3ms)  INSERT INTO "keyword_adgroups" ("name", "activate", "bid", "created_at", "updated_at", "keyword_campaign_id", "game_id") VALUES (?, ?, ?, ?, ?, ?, ?)  [["name", "3"], ["activate", true], ["bid", #<BigDecimal:7fcaac52c320,'0.1E1',9(18)>], ["created_at", 2016-12-04 13:10:19 UTC], ["updated_at", 2016-12-04 13:10:19 UTC], ["keyword_campaign_id", 36], ["game_id", 3]]
  SQL (0.2ms)  INSERT INTO "adgroup_keywords" ("keyword_id", "created_at", "updated_at", "keyword_adgroup_id", "game_id") VALUES (?, ?, ?, ?, ?)  [["keyword_id", 14], ["created_at", 2016-12-04 13:10:19 UTC], ["updated_at", 2016-12-04 13:10:19 UTC], ["keyword_adgroup_id", 84], ["game_id", 3]]
  AdgroupKeyword Exists (0.3ms)  SELECT  1 AS one FROM "adgroup_keywords" WHERE "adgroup_keywords"."keyword_id" = ? AND ("adgroup_keywords"."id" != ?) AND "adgroup_keywords"."game_id" = ? LIMIT ?  [["keyword_id", 14], ["id", 187], ["game_id", 3], ["LIMIT", 1]]

在“更新”方法中,它將達到:

  AdgroupKeyword Exists (0.2ms)  SELECT  1 AS one FROM "adgroup_keywords" WHERE "adgroup_keywords"."keyword_id" = ? AND "adgroup_keywords"."game_id" IS NULL LIMIT ?  [["keyword_id", 17], ["LIMIT", 1]]
  SQL (2.0ms)  INSERT INTO "adgroup_keywords" ("keyword_id", "created_at", "updated_at", "keyword_adgroup_id") VALUES (?, ?, ?, ?)  [["keyword_id", 17], ["created_at", 2016-12-04 13:07:03 UTC], ["updated_at", 2016-12-04 13:07:03 UTC], ["keyword_adgroup_id", 82]]
  AdgroupKeyword Exists (0.2ms)  SELECT  1 AS one FROM "adgroup_keywords" WHERE "adgroup_keywords"."keyword_id" = ? AND ("adgroup_keywords"."id" != ?) AND "adgroup_keywords"."game_id" = ? LIMIT ?  [["keyword_id", 11], ["id", 185], ["game_id", 3], ["LIMIT", 1]]

你可以嘗試運行后,該塊#update調用(內if塊)?

@adgroup.reload

@adgroup.adgroup_keywords.each do |join|
  join.update(:game_id, @adgroup.game_id)
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM