Ruby on rails RoR中的2视图1表格

Ruby on rails RoR中的2视图1表格,ruby-on-rails,forms,Ruby On Rails,Forms,我很难准确地表达我所面临的问题,但我会尝试用一个简短的描述和代码 我正在尝试向一个简单的现有应用程序添加一个功能,允许用户裁剪上传的头像图像。我在同一视图上选择文件,允许用户更新密码和其他各种帐户选项。用户提交该表单,然后呈现裁剪功能的视图。问题是,从裁剪视图来看,提交失败,因为它无法验证上一个表单中的参数。基本上,我希望所有表格都能同时提交,但有两种不同的观点 user.rb class User < ActiveRecord::Base attr_accessible :name,

我很难准确地表达我所面临的问题,但我会尝试用一个简短的描述和代码

我正在尝试向一个简单的现有应用程序添加一个功能,允许用户裁剪上传的头像图像。我在同一视图上选择文件,允许用户更新密码和其他各种帐户选项。用户提交该表单,然后呈现裁剪功能的视图。问题是,从裁剪视图来看,提交失败,因为它无法验证上一个表单中的参数。基本上,我希望所有表格都能同时提交,但有两种不同的观点

user.rb

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :avatar,
                         :crop_x, :crop_y, :crop_w, :crop_h

  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true

  mount_uploader :avatar, AvatarUploader
  attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
  after_update :crop_avatar

  def crop_avatar
    avatar.recreate_versions! if crop_x.present?
  end
end
def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    if params[:user][:avatar].present?
      render 'crop'
    else
      sign_in @user
      redirect_to @user, notice: "Successfully updated user."
    end
  else
   render 'edit'
  end
end
<% provide(:title, "Edit user") %> 
<h1>Update your profile</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for @user, :html => {:multipart => true } do |f| %>
      <%= render 'shared/error_messages', object: f.object %>

      <%= f.label :avatar %>
      <%= f.file_field :avatar %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirm Password" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
    <% end %>
  </div>
</div>
<% provide(:title, 'Crop Avatar') %>
<h1>Crop Avatar</h1>

<div class="row">
  <div class="span6 offset3">
    <%= image_tag @user.avatar_url(:large), id: "cropbox" %>

    <h4>Preview</h4>
    <div style="width:100px; height:100px; overflow:hidden">
      <%= image_tag @user.avatar.url(:large), :id => "preview" %>
    </div>

    <%= form_for @user do |f| %>
      <% %w[x y w h].each do |attribute| %>
        <%= f.hidden_field "crop_#{attribute}" %>
      <% end %>
      <div class="actions">
        <%= f.submit "Crop" %>
      </div>
    <% end %>
  </div>
</div>
edit.html.erb

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :avatar,
                         :crop_x, :crop_y, :crop_w, :crop_h

  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true

  mount_uploader :avatar, AvatarUploader
  attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
  after_update :crop_avatar

  def crop_avatar
    avatar.recreate_versions! if crop_x.present?
  end
end
def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    if params[:user][:avatar].present?
      render 'crop'
    else
      sign_in @user
      redirect_to @user, notice: "Successfully updated user."
    end
  else
   render 'edit'
  end
end
<% provide(:title, "Edit user") %> 
<h1>Update your profile</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for @user, :html => {:multipart => true } do |f| %>
      <%= render 'shared/error_messages', object: f.object %>

      <%= f.label :avatar %>
      <%= f.file_field :avatar %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirm Password" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
    <% end %>
  </div>
</div>
<% provide(:title, 'Crop Avatar') %>
<h1>Crop Avatar</h1>

<div class="row">
  <div class="span6 offset3">
    <%= image_tag @user.avatar_url(:large), id: "cropbox" %>

    <h4>Preview</h4>
    <div style="width:100px; height:100px; overflow:hidden">
      <%= image_tag @user.avatar.url(:large), :id => "preview" %>
    </div>

    <%= form_for @user do |f| %>
      <% %w[x y w h].each do |attribute| %>
        <%= f.hidden_field "crop_#{attribute}" %>
      <% end %>
      <div class="actions">
        <%= f.submit "Crop" %>
      </div>
    <% end %>
  </div>
</div>

更新您的个人资料
{:multipart=>true}do | f |%>
crop.html.erb

class User < ActiveRecord::Base
  attr_accessible :name, :email, :password, :password_confirmation, :avatar,
                         :crop_x, :crop_y, :crop_w, :crop_h

  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :password, presence: true, length: { minimum: 6 }
  validates :password_confirmation, presence: true

  mount_uploader :avatar, AvatarUploader
  attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
  after_update :crop_avatar

  def crop_avatar
    avatar.recreate_versions! if crop_x.present?
  end
end
def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    if params[:user][:avatar].present?
      render 'crop'
    else
      sign_in @user
      redirect_to @user, notice: "Successfully updated user."
    end
  else
   render 'edit'
  end
end
<% provide(:title, "Edit user") %> 
<h1>Update your profile</h1>

<div class="row">
  <div class="span6 offset3">
    <%= form_for @user, :html => {:multipart => true } do |f| %>
      <%= render 'shared/error_messages', object: f.object %>

      <%= f.label :avatar %>
      <%= f.file_field :avatar %>

      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.label :email %>
      <%= f.text_field :email %>

      <%= f.label :password %>
      <%= f.password_field :password %>

      <%= f.label :password_confirmation, "Confirm Password" %>
      <%= f.password_field :password_confirmation %>

      <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
    <% end %>
  </div>
</div>
<% provide(:title, 'Crop Avatar') %>
<h1>Crop Avatar</h1>

<div class="row">
  <div class="span6 offset3">
    <%= image_tag @user.avatar_url(:large), id: "cropbox" %>

    <h4>Preview</h4>
    <div style="width:100px; height:100px; overflow:hidden">
      <%= image_tag @user.avatar.url(:large), :id => "preview" %>
    </div>

    <%= form_for @user do |f| %>
      <% %w[x y w h].each do |attribute| %>
        <%= f.hidden_field "crop_#{attribute}" %>
      <% end %>
      <div class="actions">
        <%= f.submit "Crop" %>
      </div>
    <% end %>
  </div>
</div>

作物化身
预览
“预览”%>

一个操作不能有两个视图。再想一想,为什么您需要它,我的意思是只有当params[:user][:avatar]存在时才渲染裁剪,并且只有当您提交edit.html.erb模板时才会调用它。我认为您可以在控制器中使用另一个名为crop的方法,然后使用指定的维度更新用户的化身。

一个操作不能有两个视图。再想一想,为什么您需要它,我的意思是只有当params[:user][:avatar]存在时才渲染裁剪,并且只有当您提交edit.html.erb模板时才会调用它。我认为您可以在controller中使用另一个名为crop的方法,然后使用指定的维度更新用户的头像。

您能否尝试在crop.html.erb中创建几个隐藏输入,镜像edit.html.erb中的输入,并使用@user properties填充它们?感谢您的响应。这起作用了。我担心这可能不是最佳做法,因为页面的源代码包含密码信息。你怎么看?我需要更多的信息。关于密码。。。您是否使用Desive进行身份验证?能否尝试在crop.html.erb中创建几个隐藏输入,以镜像edit.html.erb中的输入,并使用@user properties填充这些输入?感谢您的回复。这起作用了。我担心这可能不是最佳做法,因为页面的源代码包含密码信息。你怎么看?我需要更多的信息。关于密码。。。您是否使用Desive进行身份验证?