Хобрук: Ваш путь к мастерству в программировании

Как установить внешний ключ, используя значение из вложенной формы?

У меня есть приложение Rails, которое отображает Content. Каждая часть Контента принадлежит Source, а Источник имеет_много Контента. Каждый источник состоит из name и domain.

Контент также принадлежит Edition. Мое приложение настроено так: в форме для создания/редактирования Editions я вложил поля формы для Contents, используя гем Cocoon.

Вложенные поля для содержимого включают поле link. Что мне нужно сделать, так это сравнить link с различными domains в таблице "Источники" и установить соответствующие source_id для вновь созданного/отредактированного контента.

Я думал, что могу установить соответствующие source_id в editions controller на действия update или create. Однако, поскольку единственными данными, которые я получаю, является хэш параметров со встроенным хэшем contents_attributes (который не содержит ссылки на source_id, поскольку source не задан в форме), как я могу установить 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? Или это можно сделать как есть на контроллере?


Ответы:


1

Если у вас есть значение link, установленное в форме содержимого, И у вас есть логика для определения source из значения link, тогда вам не нужно устанавливать 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
02.08.2018
  • Работал как шарм! :D В итоге я заменил ||= только на =, как вы сказали, так как я хотел, чтобы это работало всякий раз, когда ссылка редактировалась. Однако я не понял одного: почему вы использовали && в последней строке: self.source ||= link && Source.fetch_from_link(link)? На этой ноте, почему бы просто не сказать self.source = Source.fetch_from_link(link) 02.08.2018
  • Это то же самое, что и Source.fetch_from_link(link) if link, только красивее. Вы не хотите столкнуться с ошибкой, когда ссылка nil. 02.08.2018
  • О, хорошо, это потому, что выражение link && Source.fetch_from_link(link) проверяет, что оба элемента существуют, но возвращает только последний элемент, то есть Source.fetch_from_link(link)? 02.08.2018
  • Новые материалы

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..

    Что в лицо
    Очерк о возвращении физиогномики и о том, почему мы должны это приветствовать. История начинается со странной науки. Р. Тора Бьорнсдоттир, Николас О. Рул. Видимость социального класса по..

    Почему шаблоны проектирования и почему нет?
    Сложность — мать всех проблем в программировании. Программное обеспечение должно быть разработано с точки зрения того, кто его поддерживает, а не того, кто его пишет, потому что программное..

    Создание дизайна обуви с помощью машинного обучения
    Обувь. Что подождать? Я думал, что речь пойдет о машинном обучении! Ну это так. Если бы вы пошли на Amazon, сколько обуви вы бы нашли? Наверное, много, не так ли? Но много ли в них..

    GraalVM в 2022 году: итоги года
    2022 год был очень продуктивным для проекта и сообщества GraalVM. Вместе мы разработали множество новых функций, выпустили GraalVM для последних версий Java и новых платформ и увидели несколько..

    Быстрая разработка: волшебный мир больших языковых моделей
    РУКОВОДСТВО Быстрая разработка: волшебный мир больших языковых моделей Подход, основанный на данных, для получения наилучшего ответа Искусство и наука Можно ли совместить машинное..