Rails4:使用form_for提交隐藏字段的正确方法是什么

时间:2014-10-26 04:17:41

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

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

以下是实际工作流程:

  1. 用户进入“邀请页面”,其中提供了一个表单,用于输入朋友的电子邮件并显示将在电子邮件中使用的默认文本
  2. 如果用户想要他们可以点击文本并进行编辑。这将通过javascript调用邀请控制器
  3. 中的update_email方法
  4. 文本更新后,用户被重定向返回,因此用户现在可以看到包含更新文本的同一页面。 此作品,用户看到更新的文字模糊而不是默认[1-3]可能会发生任意次数
  5. 当用户提交表单时,我希望获得可以保存在数据库中的最终电子邮件版本,并触发向用户朋友发送电子邮件邀请
  6. 问题: 我一直从表单参数中获取默认文本。知道我做错了吗?

    这是表单(它的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
    

1 个答案:

答案 0 :(得分:0)

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

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

根据您的设置,rails强参数会引发错误,或者只是默默地取消不允许的参数。

我必须说你的流程有点奇怪,如果你真的使用了它可能会更好 更多RESTful模式:

<强> 1。用户进入“邀请页面”,在其中提供表单以输入朋友电子邮件并显示将在电子邮件中使用的默认文本

POST发送AJAX /invitations请求(InvitationsController #create)它应该返回UNSENT 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。用户编辑文字

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

第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