【问题标题】:Rails4: What is the correct way to use form_for for submitting a hidden fieldRails4:使用form_for提交隐藏字段的正确方法是什么
【发布时间】:2014-10-26 04:17:41
【问题描述】:

我正在尝试从表单中传递隐藏字段,该表单的值源自用户可以在网页上编辑的文本 blob。 (我使用 bootstrap-editable 让用户通过点击来编辑简介)

这是实际的工作流程:

  1. 用户进入“邀请页面”,他们会收到一个表单以输入朋友的电子邮件并显示将在电子邮件中使用的默认文本
  2. 如果用户愿意,他们可以单击文本并进行编辑。这将通过 javascript 对 Invitation 控制器中的 update_email 方法进行 post 调用
  3. 文本更新后,用户会被重定向返回,因此现在用户会看到带有更新文本的同一页面。 这行得通,用户会看到更新的文本简介而不是默认的 [1-3] 可以发生任意次数
  4. 当用户提交表单时,我希望得到最终版本的电子邮件,我可以将其保存在数据库中,并触发向用户朋友发送电子邮件邀请

问题: 我不断从表单参数中获取默认文本。知道我做错了什么吗?

这是表单(它的haml而不是html)

    #new-form
      = form_for @invitation, :url=> invitations_path(), :html => {:class => 'form-inline', :role => 'form'} do |f|
        .form-group
          = f.text_field :email, :type=> 'email', :placeholder=> 'Invite your friends via email', :class=> 'form-control invitation-email'
          = f.hidden_field :mail_text, :value => @invitation_email
        = f.submit :class => 'btn btn-primary submit-email', :value => 'Send'

这是邀请控制器:

class InvitationsController < ApplicationController
  authorize_resource
  before_filter :load_invitations, only: [:new, :index]
  before_filter :new_invitation, only: [:new, :index]
  before_filter :default_email, only: [:index]
  #helper_method :default_email

  def create
    Invitation.create!(email: params[:invitation][:email], invited_by: current_user.id, state: 'sent', mail_text: params[:invitation][:mail_text], url: {referrer_name: current_user.name}.to_param)
    redirect_to :back
  end

  def update_email
    @invitation_email = params[:value]
    flash[:updated_invitation_email] = params[:value]
    redirect_to :back
  end

  private

  def invitation_params
    params.require(:invitation).permit!
  end

  def load_invitations
    @invitations ||= current_user.sent_invitations
  end

  def new_invitation
    @invitation  = Invitation.new
  end

  def default_email
    default_text = "default text"
    @invitation_email = flash[:updated_invitation_email].blank?  ?  default_text : flash[:updated_invitation_email]
  end
end

【问题讨论】:

  • 我认为您的流程是错误的,如果用户可以编辑邮件文本,那么它为什么会隐藏在表单中?如果它是可见的,您就不必发送 ajax 请求来更新您的隐藏字段。
  • 谢谢曼迪普。用户可以像 jsfiddle.net/NfPcH/32 这样编辑文本表单。这会将 ajax 发布请求发送到 update_email 。一旦用户对编辑电子邮件文本感到满意,他们就可以在下面的文本框中输入朋友的电子邮件并点击提交。对于此提交,我将“更新”电子邮件文本作为隐藏参数传递。让我知道工作流程是否清晰,我会尝试更好地描述它
  • 啊,我看到它是一个 div 而不是一个文本字段。您可以在提交更改 @invitation_email 的 ajax 请求时发布您的日志吗?更新invitation_email 变量后是否再次呈现表单?

标签: ruby-on-rails ruby forms activerecord form-for


【解决方案1】:

假设您使用的是 Rails 4,那么您需要允许 mail_text 参数:

class InvitationsController < ApplicationController
    # ...
    private 
    def invitation_params
        params.require(:invitation).permit(:email, :mail_text) #...
    end
end

根据您的设置 rails strong 参数将引发错误或只是静默地为 null 未允许的参数。

我不得不说你的流程有点奇怪,如果你真的使用 更多 RESTful 模式:

1.用户进入“邀请页面”,向他们提供一个表格以输入朋友的电子邮件并显示将在电子邮件中使用的默认文本

/invitations (InvitationsController#create) 发送一个 AJAX POST 请求,它应该返回一个未发送的 invitation 的 JSON 表示,将返回的邀请 ID 存储在表单上。 请注意,您可能需要在您的邀请模型上设置验证,以便它允许 :email:mail_text 在创建时为空白

class Invitation < ActiveRecord::Base

    validates :email, allow_blank: true
    # ...

    # Do full validation only when mail is being sent.
    with_options if: :is_being_sent? do |invitation|
        invitation.validates :email #...
        invitation.validates :mail_text #...
    end

    # ...

    def is_being_sent?
        changed.include?("state") && state == 'sent'
    end
end

2。用户编辑文本

/invitations/:id 发送AJAX PUTPATCH 请求并更新邀请。

3.用户点击发送

/invitations/:id/send 发送 POST 请求。更新state 属性并验证。 如果有效发送邀请。向用户显示一条消息。

class InvitationsController < ApplicationController
    # ...

    # POST /invitations/:id/send
    def send
        @invitation = Invitation.find(params[:id])
        # Ensure we have latest values from form and trigger a more stringent validation
        @invitation.update(params.merge({ state: :sent })   

        if @invitation.valid?           
            @mail = Invitation.send!

            if @mail.delivered?
                # display success response  
            else
                # display error
            end
        else # record is invalid
            # redirect to edit
        end
    end
    # ...
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多