Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fields_for reset on validation error

I've seen couple similar questions here on SO but they do not fully covers my problem.

I have a pretty basic form with nested fields and the thing is, when there are any validation errors in those nested forms, all the fields_for fields are beeing reset to it's original values.

I have prepared an example super-simple app to demonstrate you the problem, it's code is available here: https://github.com/mbajur/wicked-form-reset-example

As a preview, here is controller and views code:

users_controller.rb

class UsersController < ActionController::Base
  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])

    respond_to do |format|
      if @user.update_attributes(params["user"])
        format.html { redirect_to edit_user_path(@user), notice: 'User saved.' }
      else
        format.html { render action: :edit }
      end
    end
  end
end

users/edit.html.erb

<%= form_for @user do |f| %>

  <% # ..... %>

  <h3>Assets</h3>

    <%= f.fields_for :assets, f.object.assets.first_type do |ff| %>
    <%= ff.hidden_field :asset_type %>
    <%= ff.label :value, 'Asset value:' %>
    <br>
    <%= ff.text_field :value %>
  <% end %>

  <% # ..... %>

  <hr>

  <%= f.submit %>

<% end %>

Can you give me any advice on how to deal with that?

like image 706
mbajur Avatar asked Sep 25 '26 06:09

mbajur


1 Answers

so, referring to the model code that you provided on github:

class Asset < ActiveRecord::Base
  belongs_to :user
  attr_accessible :asset_type, :value

  scope :first_type,  -> { where( asset_type: 1 ) }
  scope :second_type, -> { where( asset_type: 2 ) }
  scope :third_type,  -> { where( asset_type: 3 ) }

  validates :value, presence: true, numericality: { only_integer: true }
end

and the view you use:

  <%= f.fields_for :assets, f.object.assets.first_type do |ff| %>
    <%= ff.hidden_field :asset_type %>

    <%= ff.label :value, 'Asset value:' %>
    <br>
    <%= ff.text_field :value %>
  <% end %>

  <br><br>

  <%= f.fields_for :assets, f.object.assets.second_type do |ff| %>
    <%= ff.hidden_field :asset_type %>

    <%= ff.label :value, 'Asset value:' %>
    <br>
    <%= ff.text_field :value %>
  <% end %>

  <br><br>

  <%= f.fields_for :assets, f.object.assets.third_type do |ff| %>
    <%= ff.hidden_field :asset_type %>

    <%= ff.label :value, 'Asset value:' %>
    <br>
    <%= ff.text_field :value %>
  <% end %>

it's pretty obvious... you use scopes to reference the data. those will trigger database queries to select the data that is not persisted because of the validation errors. tadaaa!

so if you want to work on the data that is still in the model, you have to use the association!

like image 136
phoet Avatar answered Sep 27 '26 19:09

phoet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!