Rails nested form with has_many :through, how to edit attributes of join model?

Figured out the answer. The trick was:

@topic.linkers.build.build_article

That builds the linkers, then builds the article for each linker. So, in the models:
topic.rb needs accepts_nested_attributes_for :linkers
linker.rb needs accepts_nested_attributes_for :article

Then in the form:

<%= form_for(@topic) do |topic_form| %>
  ...fields...
  <%= topic_form.fields_for :linkers do |linker_form| %>
    ...linker fields...
    <%= linker_form.fields_for :article do |article_form| %>
      ...article fields...

When the form generated by Rails is submitted to the Rails controller#action, the params will have a structure similar to this (some made up attributes added):

params = {
  "topic" => {
    "name"                => "Ruby on Rails' Nested Attributes",
    "linkers_attributes"  => {
      "0" => {
        "is_active"           => false,
        "article_attributes"  => {
          "title"       => "Deeply Nested Attributes",
          "description" => "How Ruby on Rails implements nested attributes."
        }
      }
    }
  }
}

Notice how linkers_attributes is actually a zero-indexed Hash with String keys, and not an Array? Well, this is because the form field keys that are sent to the server look like this:

topic[name]
topic[linkers_attributes][0][is_active]
topic[linkers_attributes][0][article_attributes][title]

Creating the record is now as simple as:

TopicController < ApplicationController
  def create
    @topic = Topic.create!(params[:topic])
  end
end