如何使用嵌套形式的值设置外键?

How to set foreign key using value from nested form?

我有一个显示 Content 的 Rails 应用程序。每个内容 belong_to 一个 Source 和一个源 has_many 内容。每个 Source 由一个 name 和一个 domain.

组成

内容还 belongs_to 和 Edition。我的应用程序的设置方式是,在 create/edit Editions 的表单中,我使用 Cocoon gem.

嵌套了 Contents 的表单字段]

内容的嵌套字段包括一个 link 字段。我需要做的是检查 link 与来源 table 中的各种 domains 并在新的 created/edited 内容上设置相关的 source_id

我在想我可以在updatecreate动作的editions controller中设置相关的source_id。但是,由于我收到的唯一数据是带有嵌入式 contents_attributes 散列的参数散列(它没有引用 source_id,因为 source 未在表单中设置),如何我可以使用在表单上提交的 'link' 设置 source_id 吗?

这是我在 editions_controller 上的创建和更新操作:

def create
  @edition = Edition.new(edition_params)

  respond_to do |format|
    if @edition.save
      format.html { redirect_to @edition, notice: 'Edition was successfully created.' }
      format.json { render :show, status: :created, location: @edition }
    else
      format.html { render :new }
      format.json { render json: @edition.errors, status: :unprocessable_entity }
    end
  end
end

def update
  respond_to do |format|
    if @edition.update(edition_params)
      format.html { redirect_to @edition, notice: 'Edition was successfully updated.' }
      format.json { render :show, status: :ok, location: @edition }
    else
      format.html { render :edit }
      format.json { render json: @edition.errors, status: :unprocessable_entity }
    end
  end
end

这里是使用的参数:

def edition_params
  params.require(:edition).permit(:date, 
                                  :clicks, 
                                  :product_id,
                                  contents_attributes: [:id,
                                                        :heading,
                                                        :body,
                                                        :link,
                                                        :top_story,
                                                        :section_id,
                                                        :_destroy
                                                       ]
                                 )
end

我应该在带有 source_id 的表单上隐藏输入吗?或者这可以像在控制器上那样完成吗?

如果您在内容表单中设置了 link 值并且您有根据 link 的值确定 source 的逻辑,那么您不需要设置source_id 在表单中或在控制器中。

设置 source_id 的最佳位置是在模型中,因此无论您如何创建 content 记录,即从版本表单、控制台或某些其他控制器。在这种情况下,您不必担心。

在您的模型中拥有这些关联和回调应该可以解决您的目的:

class Source
  # field :name
  # field :domain

  has_many :contents

  def self.fetch_from_link(link)
    match_link_with_domains_and_return_source_record
  end
end

class Edition
  # field :date
  # field :clicks

  has_many :contents
  accepts_nested_attributes_for :contents
end

class Content
  # field :heading
  # field :body
  # field :link
  # field :top_story

  belongs_to :source
  belongs_to :edition

  before_validation :set_source

  private

  def set_source
    # Set source *only* if not already set. You can change `||=` to `=` to set it always.
    self.source ||= link && Source.fetch_from_link(link)
  end
end