【问题标题】:Saving records with has_many through relationship通过关系使用 has_many 保存记录
【发布时间】:2019-02-14 11:22:37
【问题描述】:

我有两个模型 - 用户和关键字,第三个模型关联将用户和关键字与 has_many through 关系联系起来。

我在关键字控制器中有一个创建方法,如下所示 -

def create
  @keyword = Keyword.new(keyword_params)
  if Keyword.find_by(content: params[:content]).nil?
    @keyword.save
  end

  @keyword.associations.create(:user_id => current_user.id)
  flash[:success] = "Keyword successfully created!"
  redirect_to keywords_path

在上面提到的“create”方法中,用户添加关键字后,我会检查关键字表中是否已经存在该关键字,如果不存在,则将关键字保存在关键字表中,然后保存关联表中用户与关键字的关联。

但是,如果关键字表中已经存在关键字(因为它可能已被其他用户添加),并且假设一个新用户正在将这个现有关键字添加到他的列表中,它会给我一个错误 - “你不能在 @keyword.associations.create 行中调用 create ,除非父项已保存”,因为跳过了 @keyword.save (因为该关键字已存在于数据库中)。

我正在使用 Rails 4 和 Ruby 2.0.0

我是 Rails 新手,如果你们能提供任何帮助,我将不胜感激。

更新: 添加关键字模型和关键字控制器的详细信息

型号: 用户模型:

 class User < ActiveRecord::Base
      before_save { self.email = email.downcase }
      before_create :create_remember_token

      has_many :associations
      has_many :keywords, :through => :associations

      #name
      validates :name, presence: true, length: { maximum: 50 }
    end

关键字模型:

class Keyword < ActiveRecord::Base
  has_many :questions
  has_many :associations
  has_many :users, :through => :associations
  validates :content, presence: true, uniqueness: { case_sensitive: false }
end

关联模型

 class Association < ActiveRecord::Base
      belongs_to :keyword
      belongs_to :user
      validates :user_id, :uniqueness => { :scope => :keyword_id }
    end

关键字控制器:

class KeywordsController < ApplicationController
  before_action :signed_in_user, only: [:index, :edit, :update, :destroy]

  def index
    @keywords = current_user.keywords.to_a
  end

  def new
    @keyword = Keyword.new
  end

  def create
    @keyword = Keyword.find_by(content: params[:content])
    if @keyword.nil?
      @keyword = Keyword.create(keyword_params)
    end

    @keyword.associations.create(:user_id => current_user.id)
    flash[:success] = "Keyword successfully created!"
    redirect_to keywords_path
  end

  def destroy
  end

  private
    def keyword_params
      params.require(:keyword).permit(:content)
    end
end

【问题讨论】:

    标签: ruby-on-rails has-many-through


    【解决方案1】:

    那是因为在找到关键字的情况下,您仍然引用 Keyword.new 对象,这不是 db 中的对象。

    你可以这样重写它:

    def create
      @keyword = Keyword.find_by(content: params[:content])
      if @keyword.nil?
        @keyword = Keyword.create(keyword_params)
      end
    
      @keyword.associations.create(:user_id => current_user.id)
      flash[:success] = "Keyword successfully created!"
      redirect_to keywords_path
    

    【讨论】:

    • 感谢 Vitaliy 的及时回复。不幸的是,您提出的更改给出了相同的错误-“除非保存父级,否则您不能调用 create”
    • 可能是因为 parent 有一些验证错误,如果你插入 Keyword 类的内容会有所帮助
    • 您好 Vitaliy,我在原始问题中添加了关键字模型和控制器的代码。如果我的验证有任何问题,请告诉我。感谢您的帮助。
    • 现在不能多说,直接在create方法中加bang就好了,比如Keyword.create!(keyword_params)。这样你会看到rails尝试创建关键字时是否存在验证错误,可能会有一些
    • 不幸的是同样的错误。如果我使用用户帐户创建一个不存在的全新关键字,它会通过正确的关联成功创建。但是,如果我尝试添加数据库中已经存在的关键字(因为由其他用户添加),无论我使用 create 还是 create,都会出现此错误!
    【解决方案2】:

    我认为问题可能是您在关联模型(通过表)中调用 create 而不是用户模型。 Rails 应该关心关联模型而不是你,所以尝试替换

    @keyword.associations.create(:user_id => current_user.id) 
    

    @keyword.users.create(:user_id => current_user.id)
    

    如果这些都不起作用,我建议您在创建指令之前在控制器中放置一个断点,然后您必须查看发生了什么。查看我最近的一位 cmets,了解如何使用 PRY 进行调试 https://stackoverflow.com/a/21815636/2793607

    【讨论】:

    • 谢谢拉法。我想要关键字表中的唯一关键字,但是多个用户可以添加相同的关键字,它将存储在关联表中。例如,我的用户表中有用户 1 和用户 2,关键字 1 和关键字 2 作为我的关键字表中的唯一记录。现在两个用户,用户 1 和用户 2 可以在他们的列表中拥有相同的关键字 - “关键字 1”,这将反映在关联表中。因此,关键字的唯一性应该起作用。我不希望“关键字 1”在关键字表中存储两次。
    • 我已经为所有模型添加了代码——用户、关键字和关联
    • 您现在遇到了哪个错误?打印准确的文本。
    • 我没有从关键字模型中删除唯一性验证,因为它是正确的,因为每次不同用户将相同的关键字添加到他们的列表中时,我只想保存唯一的关键字而不是相同的关键字。我得到的错误是这个 - “你不能调用 create 除非父级被保存”
    • 我明白了。我认为问题是试图在关联模型中创建(通过)而不是用户模型。 Rails 应该关心关联模型,所以只需将 @keyword.associations.create(:user_id =&gt; current_user.id) 替换为 @keyword.users.create(:user_id =&gt; current_user.id)
    【解决方案3】:

    我不确定为什么会这样,但是当我改变时
    @keyword = Keyword.find_by(content: params[:content])
    @keyword = Keyword.find_by(keyword_params),它可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多