Rails Multiform结构似乎有点过时了

时间:2010-09-01 12:35:10

标签: ruby-on-rails ruby

好的,所以我在rails中执行多个表单时遇到问题。这是下面的代码

模型

class Profile < ActiveRecord::Base
  belongs_to :user  
  has_attached_file :avatar, :styles => { :medium => "134x137>", :thumb => "111x111>", :tiny => "32x38>" }
  validates_attachment_content_type :avatar, :content_type => ['image/pjpeg','image/jpeg', 'image/x-png', 'image/png', 'image/gif']


class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy

个人资料控制器

def edit
  @user = User.find(params[:id])
  @profile = @user.profile
end

个人资料修改视图

<% form_for @user do |f| %>
 <%= f.text_field :first_name %>
 <%= f.text_field :last_name %>
 <%= f.text_field :email %>
 <%= f.password_field :password %>
 <%= f.password_field :password_confirmation %>
<input id="send_update" name="send" type="submit" value="Update" />
<% end %>


<% form_for @profile , :html => { :multipart => true } do |f| %>
<%= render :partial => 'form', :locals => {:f => f, :profile => @profile, :title => 'Edit Profile'} %>
<%= submit_tag 'Update', :style => 'text_align:right'%>
<% end %>

个人资料_form partial

<label>Upload Avatar</label>
<tr><%= f.file_field :avatar %></tr>

所以基本上我在编辑视图中有两个表单,当我点击第二个更新来更新头像我转到用户更新,我得到这个flash错误“抱歉,出了问题”

def update
  @user = User.find(params[:id])    
  current_email = @user.email
if @user.update_attributes(params[:user])
  UserMailer.deliver_email_changed (@user) if email_changed?(current_email, @user.email)
  flash[:notice] = "<h1>Account updated!</h1>"
  redirect_to edit_user_path(@user)
else
  flash.now[:error] = "Sorry, something went wrong"
  render :action => :edit
end
end

我的问题是

  1. 有没有更好的方法来构建这个,所以也许我有一个表格?
  2. 为什么现在没有保存,导致问题是什么?

2 个答案:

答案 0 :(得分:0)

故障排除会有所帮助:

  1. 删除if / else并保留@ user.update_attributes(params [:user])。 Rails会给你一个更详细的错误信息。
  2. 检查表单结构(html源代码),尤其是字段命名。
  3. 检查数据库语句的日志文件
  4. HTH

答案 1 :(得分:0)

您用来更新的方法是错误的,它在语法上是无效的(您错过了end)。它应该是:

def update
  @user = User.find(params[:id])    
  current_email = @user.email
  if @user.update_attributes(params[:user])
    UserMailer.deliver_email_changed (@user) if email_changed?(current_email, @user.email)
    flash[:notice] = "<h1>Account updated!</h1>"
    redirect_to edit_user_path(@user)
  else
    flash.now[:error] = "Sorry, something went wrong"
    render :action => :edit
  end
end

它应该是两种形式,因为我猜你不希望在用户执行其他操作时提交一个表单的任何值。

现在,整理你的控制器。您在ProfilesController上调用@user = User.find(params[:id]),但您传递的ID是用户的ID。这应该在用户的控制器上,并从那里更新相关的配置文件,或者你应该收到配置文件对象的id。

我会选择第一个。您可以使用accepts_nested_attributes_for更新用户的个人资料对象,您的表单将如下:

<% form_for @user do |f| %>
  <%= f.text_field :first_name %>
  <%= f.text_field :last_name %>
  <%= f.text_field :email %>
  <%= f.password_field :password %>
  <%= f.password_field :password_confirmation %>
  <%= f.submit, :id => ... %>
<% end %>

<% form_for @user, :html => { :multipart => true } do |f| %>
  <% f.fields_for :profile do |profile_form| %>
    <%= render :partial => 'form', :locals => {:f => profile_form, :title => 'Edit Profile'} %>
    <%= submit_tag 'Update', :style => 'text_align:right'%>
  <% end %>
<% end %

如果错误是密码不能为空,可能是由于validates_presence_of :password, :password_confirmation。您应该使用conditional validation那里