Nested form not updating the database
I have a nested form that does not update the database.
Models:
User:
has_many :designs, :dependent => :restrict
accepts_nested_attributes_for :designs
attr_accessible :designs_attributes
Design:
belongs_to :user
Designs Controller:
def update
@design = Design.find(params[:id])
@user = User.find_by_id(@design.user_id)
@points = (@user.points + 5000)
if @design.update_attributes(params[:design])
flash[:success] = "Design aproved"
redirect_to designindex_path
else
@title = @design.name + %(, created by ) + @design.user.username
render 'edit'
end
end
And here is the form:
<%= form_for @user, :html => { :multipart => true } do |f| %>
<%= f.hidden_field(:points, {:value => @points}) %>
<%= f.fields_for :designs, @design do |d| %>
<div class="field">
<%= d.label :total_price, %(New price) %><br />
<%= d.text_field :total_price %>
</div>
<%= d.hidden_field(:aproved, {:value => 1}) %>
<% end %>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
Also, when I push Submit button, it redirects me to root_path.
Looking in the console output I found this:
Started POST "/users/101" for 127.0.0.1 at 2011-09-29 15:31:16 +0200
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"N16nb5i/PUPftGHs3uvnnLwrp8e/PQB88w0OU6DLGko=",
"user"=>{"points"=>"7500", "designs_attributes"=>{"0"=>{"total_price"=>"20",
"aproved"=>"1", "id"=>"66"}}}, "commit"=>"Submit", "id"=>"101"}
The problem here seems to be the following:
An user has_many designs, but when doing the POST request the controller does not specify which one is being updated. Anyway, the users.points attribute is neither updated.
Update
Ok, I got the problem, I have this in users_controller.rb:
before_filter :authenticate, :only => [:index, :edit, :update, :destroy]
before_filter :correct_user, :only => [:edit, :update]
And I'm trying to update another user's information from an admin account. Can I do this in any way?
Here is the code for those:
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
def current_user?(user)
user == cur开发者_开发技巧rent_user
end
def authenticate
deny_access unless signed_in?
end
def signed_in?
!current_user.nil?
end
You'll want to do:
<%= f.fields_for :designs, @design do |d| %>
...
<% end %>
This will make sure it uses the designs_attributes
attribute (and will default to 0 index I believe). Can't remember if you'll need to wrap the @design
in an array ([@design]
), don't believe you do.
Your params should look like {:user => {:designs_attributes => { '0' => {:id => 1, ... } } } }
Ok, got it working, just modified correct_user function as follows
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user) || current_user.admin
end
精彩评论