安装I18n后Ruby on Rails含datetime输入的表单失效问题求助
Hey there, let's break down why your datetime-including forms are failing to create Blackoutperiod records after setting up I18n. From your logs, we can see the transaction is rolling back without a clear error, which points to model validation issues or parameter parsing conflicts. Here's how to fix it step by step:
1. Fix the Reserved Keyword Conflict
First off, you're using end as a datetime field name—and that's a reserved Ruby keyword (it's used to close code blocks). Rails struggles to handle this properly, especially when I18n parses datetime parameters, which is almost certainly causing part of your problem.
How to fix it:
- Generate a migration to rename the field:
rails generate migration RenameEndToEndAtInBlackoutperiods - Open the generated migration file and update it to:
class RenameEndToEndAtInBlackoutperiods < ActiveRecord::Migration[6.1] # Use your actual Rails version def change rename_column :blackoutperiods, :end, :end_at end end - Run the migration:
rails db:migrate - Update all references to the field across your code:
- In
BlackoutperiodsController#blackoutperiod_params, change:endto:end_at - In your
_form.html.erb, replacef.input :endwithf.input :end_at, label: "End" - Double-check any other places (like views or model logic) where you used the old
:endfield name
- In
2. Resolve Belongs_to Validation Failures
Looking at your Blackoutperiod model, you have two belongs_to associations:
belongs_to :resource belongs_to :entreprise
In Rails 5 and later, belongs_to associations are required by default. Since your form doesn't include inputs for resource_id or entreprise_id, and you're not setting these values in the controller, the model is failing validation and rolling back the transaction.
Two ways to fix this:
Option A: Make the associations optional
If these associations aren't required for a Blackoutperiod, update your model:
class Blackoutperiod < ApplicationRecord belongs_to :user belongs_to :resource, optional: true belongs_to :entreprise, optional: true end
Option B: Auto-assign the required associations
If they are required, set them in your controller's create method (e.g., link to the current user's entreprise):
def create @blackoutperiod = current_user.blackoutperiods.build(blackoutperiod_params) # Assuming your User model has an `entreprise` association @blackoutperiod.entreprise = current_user.entreprise # Add similar logic for :resource if needed if @blackoutperiod.save redirect_to blackoutperiods_path else render 'new' end end
3. Configure I18n Datetime Parsing Formats
I18n can interfere with how Rails parses datetime parameters from forms. Make sure your locale files have the correct formats to match what your form is submitting.
Example for English (config/locales/en.yml):
en: date: formats: default: "%Y-%m-%d" time: formats: default: "%Y-%m-%d %H:%M:%S" datetime: input: formats: ["%Y-%m-%d %H:%M", "%Y-%m-%d"]
Adjust this to match your locale's preferred date/time format if you're using a non-English locale.
4. Debug Validation Errors
To confirm exactly what's failing, add error messages to your form. This will show you the specific validation issues when submission fails.
Add this to your _form.html.erb (right after opening the simple_form_for block):
<% if @blackoutperiod.errors.any? %> <div class="alert alert-danger"> <h4><%= pluralize(@blackoutperiod.errors.count, "error") %> stopped this record from saving:</h4> <ul> <% @blackoutperiod.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>
Once you implement these fixes, your Blackoutperiod creation should work as expected with I18n enabled.
内容的提问来源于stack exchange,提问作者user9680695

