You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby新手求助:Padrino表单如何向多关联表写入多行数据

Handling Multi-Language Article Form Submissions in Padrino (Single-Form Experience)

Hey there fellow Ruby newbie! I totally get wanting to treat your multi-table setup like a single model when building forms—nested attributes are your best friend here. Let’s walk through step-by-step how to make this work in Padrino.

1. Define Model Associations with Nested Attributes Support

First, we need to set up your models to accept nested attributes from their associated tables. This tells Padrino (and Active Record under the hood) that we want to create/update child records alongside the parent Article in one go.

# app/models/article.rb
class Article < ActiveRecord::Base
  has_many :article_lngs, dependent: :destroy
  # Allow Article to accept attributes for its ArticleLng records
  accepts_nested_attributes_for :article_lngs, allow_destroy: true
end

# app/models/article_lng.rb
class ArticleLng < ActiveRecord::Base
  belongs_to :article
  has_one :article_data, dependent: :destroy
  # Allow ArticleLng to accept attributes for its ArticleData record
  accepts_nested_attributes_for :article_data
end

# app/models/article_data.rb
class ArticleData < ActiveRecord::Base
  belongs_to :article_lng
end

The accepts_nested_attributes_for method is key here—it lets us pass nested parameters through the parent model’s form.

2. Build the Single Form with Nested Fields

Next, we’ll create a form that lets users input data for all language versions in one place. We’ll use fields_for to nest the ArticleLng and ArticleData fields under the main Article form.

Let’s use ERB for example (adjust to Haml if that’s your preference):

# app/views/articles/new.html.erb
<%= form_for @article, url: articles_path do |f| %>
  <%# Optional: Add any top-level Article fields here (if your article table has extra columns) %>

  <%# Loop through your target languages—replace with your actual locale codes %>
  <% ['zh-CN', 'en-US'].each do |locale| %>
    <div class="language-section">
      <h3>Article Version: <%= locale %></h3>
      
      <%# Nested fields for ArticleLng %>
      <%= f.fields_for :article_lngs, @article.article_lngs.build(language: locale) do |lng_form| %>
        <%= lng_form.hidden_field :language %>
        
        <%# Nested fields for ArticleData (linked to this ArticleLng) %>
        <%= lng_form.fields_for :article_data, lng_form.object.build_article_data do |data_form| %>
          <div class="form-group">
            <%= data_form.label :title %>
            <%= data_form.text_field :title, class: "form-control" %>
          </div>
          <div class="form-group">
            <%= data_form.label :content %>
            <%= data_form.text_area :content, class: "form-control", rows: 8 %>
          </div>
        <% end %>
      <% end %>
    </div>
  <% end %>

  <div class="form-actions">
    <%= f.submit "Create Multi-Language Article", class: "btn btn-primary" %>
  </div>
<% end %>

We use .build here to pre-create empty ArticleLng and ArticleData objects for each language—this ensures the form generates the correct input names so Padrino can parse the nested data later.

3. Update the Controller to Handle Nested Parameters

Finally, we need to whitelist the nested parameters in your controller so Padrino allows them to pass through to the model. Here’s how your ArticlesController should look:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def new
    # Initialize a blank Article to attach our nested objects to
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)
    
    if @article.save
      redirect_to articles_path, notice: "All article versions created successfully!"
    else
      # If validation fails, re-render the form with errors
      render :new
    end
  end

  private

  def article_params
    params.require(:article).permit(
      # Add any top-level Article attributes here if needed
      article_lngs_attributes: [
        :language,
        article_data_attributes: [
          :title, :content # Add all your ArticleData columns here
        ]
      ]
    )
  end
end

The article_params method is critical—we explicitly list all nested attributes we want to allow, which prevents mass assignment vulnerabilities.

Extra Tips for Polish

  • Add Validations: Make sure to add validations to your models to ensure data integrity. For example:
    # In ArticleLng
    validates :language, presence: true, uniqueness: { scope: :article_id }
    # In ArticleData
    validates :title, :content, presence: true
    
  • Dynamic Languages: If your supported languages aren’t fixed, pull them from a config file or database instead of hardcoding the array.
  • Edit Functionality: For editing existing articles, pre-load the associated article_lngs and article_data in the edit action so the form populates with existing data.

内容的提问来源于stack exchange,提问作者Levi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:11:11