रेल नेस्टेड फॉर्म has_many के माध्यम से: कैसे, शामिल होने के मॉडल की विशेषताओं को संपादित करने के लिए?


103

जब आप ac अवधारणाओं_nested_attributes_for का उपयोग करते हैं, तो आप किसी मॉडल के गुणों को कैसे संपादित करते हैं?

मेरे पास 3 मॉडल हैं: विषय और लेख लिंकर्स द्वारा जुड़े हुए हैं

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

इसलिए जब मैं विषय नियंत्रक की "नई" कार्रवाई में लेख का निर्माण करता हूं ...

@topic.articles.build

... और विषयों को नेस्टेड फॉर्म / new.html.erb ...

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

... रेल स्वचालित रूप से लिंकर बनाता है, जो महान है। अब मेरे प्रश्न के लिए: मेरे लिंकर मॉडल में भी विशेषताएँ हैं जिन्हें मैं "नए विषय" फॉर्म के माध्यम से बदलना चाहता हूं। लेकिन रॉलर जो स्वचालित रूप से बनाता है, उसके सभी विशेषताओं के लिए शून्य मान होते हैं सिवाय topic_id और article_id के। मैं उन अन्य लिंकर विशेषताओं के लिए "नए विषय" फॉर्म में फ़ील्ड कैसे डाल सकता हूं ताकि वे शून्य से बाहर न आएं?


3
मैं वही काम करने की कोशिश कर रहा हूं जो आप केवल एक नई / कार्रवाई बनाने में कर रहे हैं ... मैं सोच रहा हूं कि क्या आप अपने नियंत्रक कार्यों को साझा कर सकते हैं। मैं एक के रूप में एक का उपयोग कर के Userमाध्यम से एक बनाना चाहते हैं ... लेकिन मैं यह नहीं पता कर सकते हैं कि नए और बनाने के लिए कार्रवाई की तरह लग रहे हो ... तुम बुरा होगा? AccountRelationshiplinker
मोहम्मद

जवाबों:


90

इसका उत्तर पता लगा। चाल थी:

@topic.linkers.build.build_article

यह लिंकर्स बनाता है, फिर प्रत्येक लिंकर के लिए लेख बनाता है। तो, मॉडल में:
topic.rb को accepts_nested_attributes_for :linkers
linker.rb की जरूरत हैaccepts_nested_attributes_for :article

फिर फॉर्म में:

<%= 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...

13
मुझे बताएं कि क्या यह मददगार था
आर्कोलाई

13
Form_for और field_for जरूरत <% =%> बजाय <%%> आप रेल 3. उपयोग कर रहे हैं: 3 अद्यतन रेल
Arcolye

मैं आपके द्वारा जोड़े गए दो एक्सेप्ट्स_nested_attributes_for लाइनों के आसपास कोड बैकटिक्स जोड़ूंगा। कोड को स्कैन करते समय मैंने उस जानकारी को बार-बार याद किया - एक बार जब मैंने इसे अच्छी तरह से पढ़ा, तो मैंने उस छूटी हुई डिटेल को पकड़ा और इससे मेरी समस्या हल हो गई। धन्यवाद!
TJ Schuck

2
ईमानदारी से, यह पूर्ण उदाहरण है कि rubyonrails.org गाइड की जरूरत है।
अनहोबेकाड

दृश्य स्पष्टता वास्तव में एक लंबा रास्ता तय करती है, टीजे शुक।
अहानिबेक्स्ड

6

जब रेल द्वारा उत्पन्न प्रपत्र रेल के लिए प्रस्तुत किया जाता है controller#action, तो paramsइसके समान संरचना होगी (कुछ बनाए गए विशेषताओं को जोड़ा गया है):

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

ध्यान दें कि linkers_attributesवास्तव में कुंजी के Hashसाथ शून्य-अनुक्रमित कैसे किया जाता है String, और नहीं Array? खैर, इसका कारण यह है कि प्रपत्र फ़ील्ड कुंजियाँ जो सर्वर को भेजी जाती हैं वे इस तरह दिखती हैं:

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

रिकॉर्ड बनाना अब इतना आसान है:

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

मुझे यकीन नहीं है, लेकिन मुझे लगता है कि सभी के साथ ग्रहण किया गया हैaccepts_nested_attributes_for
आर्कोलाई

2
@Arcolye - इस तरह से एक एसोसिएशन के लिए इंटरनेट पर इस जानकारी को ढूंढना उस समय इस तरह का दर्द था - शायद उस दिन मेरा google-fu बंद था। मैं इसे कम से कम यहाँ दस्तावेज़ करना चाहता था क्योंकि मैं अपने सह-कार्यकर्ता के रूप में था और मैंने एक शून्य अनुक्रमित हैश के बजाय लिंक्ड_ट्रेन को सरणी में परिवर्तित कर दिया था। उम्मीद है कि इस tidbit भविष्य में किसी की मदद करता है :)
डैनियल Doezema

3

आपके समाधान में has_one का उपयोग करते समय एक त्वरित GOTCHA। मैं बस इस धागे में उपयोगकर्ता KandadaBoggu द्वारा दिए गए उत्तर को कॉपी पेस्ट करूंगा


buildविधि हस्ताक्षर के लिए अलग है has_oneऔर has_manyसंघों।

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

has_manyएसोसिएशन के लिए बिल्ड सिंटैक्स :

user.messages.build

has_oneएसोसिएशन के लिए बिल्ड सिंटैक्स :

user.build_profile  # this will work

user.profile.build  # this will throw error

अधिक विवरण के लिए has_oneएसोसिएशन प्रलेखन पढ़ें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.