Rails - 从子表单创建父实例

时间:2016-07-21 09:47:33

标签: ruby-on-rails ruby-on-rails-4 parent-child nested-forms

我试图做一些' accepts_nested_attributes'的倒数。我想从' children_controller #create'创建一个父实例。也许你会有一些建议或解释我与此无关。我对所有评论都持开放态度!

我有一个客户端模型:

class Client < ActiveRecord::Base
  has_one :magazine
  validates :name, presence: true, uniqueness: true
end

杂志模特:

class Magazine < ActiveRecord::Base
  belongs_to :client
  validates :client, :launch_date, presence: true
  # accepts_nested_attributes_for :client
end

我正在使用react-rails gem并在/magazines我有一个表单来创建一个带有文本字段的新杂志,以提供客户名称。

在我的magazines_controller.rb中,我提出了以下内容

def create
  @client = Client.find_by_name(magazine_params[:client_id])
  @selected_magazine = Magazine.new(magazine_params)
  authorize @selected_magazine
  if @client
    @selected_magazine.client = @client
  else
    @client = Client.new(name: magazine_params[:client_id])
    @client.save
    @selected_magazine.client = @client
  end
  # @client = Client.where(name: magazine_params[:client_id]).first_or_create
  # @selected_magazine.client = @client if @selected_magazine.client_id.to_i == 0
  @title = magazine_params[:title]
  @selected_issue = nil
  @issues = nil
  @selected_magazine.save
  binding.pry
  @magazines = policy_scope(Magazine)
end

def magazine_params
  magazine_params = params.require(:magazine).permit(:title, :analytics_id, :launch_date, :client_id)
  # if @client
  #   params[:magazine][:client_id] = @client.id
  #   magazine_params.merge!(params[:magazine])
  # end
  return magazine_params
end

我总是以PG ::错误:

结束
PG::ForeignKeyViolation - ERROR:  insert or update on table "magazines" violates foreign key constraint "fk_rails_cd907cfe6d"
DETAIL:  Key (client_id)=(51) is not present in table "clients".

好像客户端没有保存在数据库中。当我binding.pry并致电Client.all after @client.save时,它不会返回我的新客户。

我有点惊讶,因为在另一个项目中我有类似的问题并且这样做很好。供您参考:

# Previous Project
# Gemfile.lock
pg (0.18.3)
rails (4.2.0)

#Current Project
# Gemfile.lock
pg (0.18.4)
rails (4.2.5.1)

提前感谢您的帮助。如果您对在child_controller的子项之前创建父实例有良好做法有任何建议,我真的很感兴趣。

PS1:在控制器中,我首先尝试使用注释或创建,输出仍然相同。 PS2:如果您需要有关Gemfile的更多信息,请告诉我。

3 个答案:

答案 0 :(得分:1)

您可能想对您的关联尝试inverse_of,例如:

class Client < ActiveRecord::Base
  has_one :magazine, inverse_of: :client
  validates :name, presence: true, uniqueness: true
end

class Magazine < ActiveRecord::Base
  belongs_to :client, inverse_of: magazine
  validates :client, :launch_date, presence: true
  # accepts_nested_attributes_for :client
end

进一步阅读:http://guides.rubyonrails.org/association_basics.html#bi-directional-associations

但是,一般用例是has_many

答案 1 :(得分:0)

请尝试下面的代码,这应该可以解决问题。我认为问题是你在保存客户端之前试图保存杂志。此外,如果不是,请检查 @ client.valid?是否为真,请检查 @ client.errors 。另外,按如下所示重写控制器,

def create
  @client = Client.find_by_name(params[:magazine][:client_id])

  if @client.nil?
    @client = Client.new(name: params[:magazine][:client_id])
  end

  @selected_magazine = @client.magazines.new(magazine_params)

  authorize @selected_magazine

  @title = magazine_params[:title]
  @selected_issue = nil
  @issues = nil

  @client.save
  @magazines = policy_scope(Magazine)
end

def magazine_params
  params.require(:magazine).permit(:title, :analytics_id, :launch_date)
end

答案 2 :(得分:0)

您可以参考http://www.amooma.de/screencasts/2015-01-22-nested_forms-rails-4.2/。用例子解释得很好。它可以解决你的问题。