【问题标题】:How can I get form_for to autopopulate fields based upon a non-model hash?如何让 form_for 根据非模型哈希自动填充字段?
【发布时间】:2011-03-07 13:06:48
【问题描述】:

我正在 Rails 中构建一个多步骤表单。它不是 javascript 驱动的,因此每个页面都有自己的控制器操作,例如“step1”“step2”等。我知道如何通过 JQuery 执行多步向导,但我不知道如何在不进入 javascript 的情况下保持每页的 rails 验证,因此这样。

无论如何,我的模型是 User 对象,但我将所有变量存储在任意 Newuser 变量中,并在视图中使用以下内容:

<% form_for :newuser, :url => { :action => "step3" } do |u| %>

在控制器中,我使用以下方法将当前页面的信息与整体哈希合并:

session[:newuser].merge!(params[:newuser])

这很好用,只是如果用户点击返回上一页,则不再填充这些字段。我如何保持他们的数量?我是否需要更改 form_for 中的对象以某种方式引用 session[:newuser] 哈希?

编辑:

我想我正在寻找有关 form_for 如何在表单中自动填充字段的更多信息。如果它不是围绕模型构建的,而是基于任意散列(在本例中为 session[:newuser]),我如何让它自动填充?

【问题讨论】:

    标签: ruby-on-rails forms hash


    【解决方案1】:

    这就是我们如何使用验证完成多步骤表单

    class User < ActiveRecord::Base
    
      attr_writer :setup_step
    
      with options :if => :is_step_one? do |o|
        o.validates_presence_of :name
      end
    
      with options :if => :is_step_two? do |o|
        o.validates_presence_of :email
      end
    
      def setup_step
        @setup_step || 1
      end
    
      def is_step_one?
        setup_step == 1
      end
    
      def is_step_two?
        setup_step == 2
      end
    
      def last_step?
        is_step_two? #change this to what your last step is
      end
    end
    

    然后在控制器中:

    UsersController
      SETUP_STEPS{1 => 'new', 2 => 'step_two'}
    
      def new
        @user = User.new
      end
    
      def step_two
      end
    
      def create
        @user = User.new(params[:user])
    
        if !@user.valid?
          render :action => SETUP_STEPS[@user.setup_step]
        elsif @user.last_step?
          @user.save
          #do stuff
        else
          render :action => SETUP_STEPS[@user.setup_step]
        end
      end
    end
    

    然后在您的表单中,它们就像任何其他 Rails 表单一样,除了一个例外,您需要一个隐藏字段来保存您之前步骤中的值。

    - form_for @user, :url => users_path do |f|
      - [:login, :password].each do field
        = f.hidden_field field
    

    【讨论】:

    • 您有很多好主意...谢谢 Geoff。我的一个问题是我在隐藏字段中有信用卡信息和其他我不想要的信息,因此是会话数据。但对于其余的东西,它听起来不错! :)
    • 明白了,您可以将信用卡藏在会话变量中并在保存之前将其拉入,这样信用卡就是一个异常值。或者你可以把信用卡留到最后一步:)
    【解决方案2】:

    仍然为您的人群使用课程怎么样?

    class User
      attr_accessor :credit_card, :name, :likes_fried_chicken
    
      def initialize(options = {})
        options.each do |key, value|
          self.send("#{key}=", value)
        end
      end
    end
    

    如果你想包含一些验证,你可以在这里使用一些无表模型函数。

    然后在您的控制器步骤中:

    def step_one
      @user = User.new(session[:new_user])
    end
    

    您的表单应该可以继续工作。

    另一种选择是直接从会话哈希中设置表单对象的值

    - form_for :user, :url => step_2_path do |f|
      = f.text_field :name, :value => session[:new_user][:name]
    

    【讨论】:

    • Geoff,通过为每个控制器设置一个新用户,您的解决方案与我正在使用的解决方案接近...我想我只是想知道理论上如何根据任意非自动填充表单模型哈希。如果我没有得到另一个答案,我会给你 50 分。 :)
    • self.send("#{key}=", value) 似乎绕过了 ActiveRecord attr_protected 和 attr_accessible 批量分配安全功能:api.rubyonrails.org/classes/ActiveRecord/Base.html#M001796
    猜你喜欢
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多