Rails Simple Forms报错:undefined method `model_name' for nil:NilClass求助
Hey there! That error pops up because Simple Form is built to work with model objects by default—when you don’t pass it a valid "model-like" object, it doesn’t know how to handle the form context. Let’s break down two straightforward solutions for your table export selection form:
Option 1: Use OpenStruct as a Mock Model
Ruby’s OpenStruct lets you create objects with arbitrary attributes, which makes it perfect for mimicking a real model when you don’t have one.
Step 1: Initialize the Mock Model in Your Controller
In the action that renders your form, create an OpenStruct instance. Initialize it with params on POST requests (to retain selections if there’s an issue) and an empty instance on GET requests:
def export if request.post? @export_selection = OpenStruct.new(export_selection_params) # Add your zip generation logic here # e.g., create_zip_with_tables(@export_selection.to_h.select { |k, v| v }) else @export_selection = OpenStruct.new end end private def export_selection_params # Replace available_tables with your actual list of table names params.require(:export_selection).permit(available_tables.map(&:to_sym)) end
Step 2: Update Your Simple Form
Pass the @export_selection object to simple_form_for—it’ll behave just like a regular model:
<%= simple_form_for @export_selection, url: export_path, method: :post do |f| %> <% available_tables.each do |table_name| %> <%= f.input table_name, as: :boolean, label: table_name.humanize %> <% end %> <%= f.button :submit, "Download Selected Tables Zip" %> <% end %>
Option 2: Use simple_form_tag (No Mock Model Needed)
If your form is simple (just checkboxes here), simple_form_tag is even more direct—it works like Rails’ built-in form_tag but with Simple Form’s styling, no model required.
Update Your Form Code
Replace simple_form_for with simple_form_tag and use basic checkbox helpers:
<%= simple_form_tag export_path, method: :post do %> <% available_tables.each do |table_name| %> <%= check_box_tag "export_tables[]", table_name, false, id: "export_tables_#{table_name}" %> <%= label_tag "export_tables_#{table_name}", table_name.humanize %> <% end %> <%= submit_tag "Download Selected Tables Zip" %> <% end %>
Access Selections in Your Controller
You’ll get an array of selected table names in params[:export_tables]:
def export selected_tables = params[:export_tables] || [] # Generate your zip file using selected_tables end
Which Option Should You Pick?
- Go with Option 1 if you might add more fields later, or want to use Simple Form’s built-in validation/error handling.
- Go with Option 2 for a lightweight, no-fuss solution perfect for simple selection forms like yours.
Either way, you’ll eliminate that annoying model_name error and have a working form for users to pick tables for export.
内容的提问来源于stack exchange,提问作者s4342re41

