使用has_many通过关系保存记录

时间:2014-02-17 22:38:08

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

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

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

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

在上面提到的“创建”方法中,在用户添加关键字后,我正在检查关键字表中是否已存在该关键字,如果不存在,则将关键字保存在关键字表中,然后保存关联表中用户和关键字之间的关联。

但是,当关键字表中已存在关键字时(因为它可能已由其他用户添加),并且假设新用户将此现有关键字添加到其列表中,则会给出错误 - “您不能除非在@ 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

3 个答案:

答案 0 :(得分:0)

这是因为在找到关键字的情况下,你仍然会引用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

答案 1 :(得分:0)

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

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

通过

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

如果这些都不起作用,我建议你在创建指令之前在控制器中放置一个断点,你必须看看发生了什么。查看我的一篇关于如何使用PRY https://stackoverflow.com/a/21815636/2793607

进行调试的评论

答案 2 :(得分:0)

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