Rails zagnieżdżony formularz Z ma wiele: through, jak edytować atrybuty modelu join?

Jak edytować atrybuty modelu join przy użyciu accepts_nested_attributes_for?

Mam 3 modele: tematy i artykuły połączone przez Linkerów

class Topic < ActiveRecord::Base
  has_many :linkers
  has_many :articles, :through => :linkers, :foreign_key => :article_id
  accepts_nested_attributes_for :articles
end
class Article < ActiveRecord::Base
  has_many :linkers
  has_many :topics, :through => :linkers, :foreign_key => :topic_id
end
class Linker < ActiveRecord::Base
  #this is the join model, has extra attributes like "relevance"
  belongs_to :topic
  belongs_to :article
end

Więc kiedy buduję artykuł w" nowej " akcji kontrolera tematów...

@topic.articles.build

...i utwórz zagnieżdżony formularz w topics / new.html.erb...

<% form_for(@topic) do |topic_form| %>
  ...fields...
  <% topic_form.fields_for :articles do |article_form| %>
    ...fields...

...Rails automatycznie tworzy łącznik, co jest świetne. teraz moje pytanie: mój model linkera ma również atrybuty, które chcesz mieć możliwość zmiany za pomocą formularza "nowy temat". Ale linker tworzony automatycznie przez Rails ma zerowe wartości dla wszystkich swoich atrybutów z wyjątkiem topic_id i article_id. Jak Mogę umieścić pola dla innych atrybutów linkera w formularzu "nowy temat", aby nie wyszły na zero?

Author: Arcolye, 2010-02-02

3 answers

Wymyśliłem odpowiedź. Sztuczka była:

@topic.linkers.build.build_article

To buduje linkery, a następnie buduje artykuł dla każdego linkera. Więc w modelach:
temat.potrzeby rb accepts_nested_attributes_for :linkers
linker.potrzeby rb accepts_nested_attributes_for :article

Następnie w formie:

<%= 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...
 90
Author: Arcolye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 05:31:16

W przypadku, gdy formularz wygenerowany przez Rails zostanie przesłany do Rails controller#action, params będzie miał strukturę podobną do tej (dodano kilka atrybutów):

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."
        }
      }
    }
  }
}

Zauważ, że linkers_attributes jest tak naprawdę indeksowane Hash z String kluczami, a nie Array? Cóż, dzieje się tak dlatego, że klucze pól formularza wysyłane do serwera wyglądają tak:

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

Tworzenie rekordu jest teraz tak proste jak:

TopicController < ApplicationController
  def create
    @topic = Topic.create!(params[:topic])
  end
end
 6
Author: Daniel Doezema,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 16:09:21

Szybka pomoc przy użyciu has_one w Twoim rozwiązaniu. Po prostu skopiuję wklejenie odpowiedzi udzielonej przez Użytkownika KandadaBoggu W w tym wątku.


Sygnatura metody build jest inna dla asocjacji has_one i has_many.

class User < ActiveRecord::Base
  has_one :profile
  has_many :messages
end

Składnia budowania dla has_many Asocjacja:

user.messages.build

Składnia budowania dla has_one Asocjacja:

user.build_profile  # this will work

user.profile.build  # this will throw error
Więcej informacji można znaleźć w dokumentacji Stowarzyszenia

has_one .

 3
Author: 8bithero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:45:55