【问题标题】:Rails Merge Form FieldsRails 合并表单字段
【发布时间】:2014-07-04 12:45:27
【问题描述】:

我有一个 Rails 3.2.18 应用程序,我在其中对模型执行简单的创建/更新操作。

有一个叫做sms的字段,我使用ActionMailer以2812222222@vtext.com的形式向某人的手机发送消息。目前我手动输入这个很好,但我希望其他人能够输入电话号码,选择运营商并将这两个项目合并为短信字段中的正确格式,再次为 2812222222@vtext.com。比起必须记住完整的 sms-to-email 地址,它更便于用户使用。

我认为我可以通过 JS/JQuery 完成大部分工作,但我不确定如何开始。

我希望他们能够以 281-555-4444 格式输入电话号码,并让运营商选择 Tmobile、Verizon 等下拉列表并替换 @tmomail.net、@vtext。 com等,剥离(正则表达式)电话号码并将其与运营商(@vtext.com)合并到短信字段中。

如果有人能直接指出我的正确方向,将不胜感激。

更新:

我想我可以使用辅助方法来定义载体:

def phone_carriers
{
  "All Tell" => "@message.alltel.com",
  "AT&T" => "@txt.att.net",
  "Boost" => "@myboostmobile.com",
  "Cellular South" => "@csouth1.com",
  "Centennial Wireless" => "@cwemail.com",
  "Cincinnati Bell" => "@gocbw.com",
  "Cricket Wireless" => "@sms.mycricket.com",
  "Metro PCS" => "@mymetropcs.com",
  "Powertel" => "@ptel.net",
  "Qwest" => "@qwestmp.com",
  "Rogers" => "@pcs.rogers.com",
  "Sprint" => "@messaging.sprintpcs.com",
  "Suncom" => "@tms.suncom.com",
  "T-Mobile" => "@tmomail.net",
  "Telus" => "@msg.telus.com",
  "U.S. Cellular" => "@email.uscc.net",
  "Verizon" => "@vtext.com",
  "Virgin Mobile USA" => "@vmobl.com"
}

结束

将 attr_accessor :carrier 添加到 Person 模型

然后在表单中执行如下操作:

<%= f.input :phone, placeholder: "555-555-5555", required: true, input_html: {required: true} %>

<%= f.select :carrier, phone_carriers.map{ |k, v| [k, v] }, {include_blank: true}, {placeholder: "Select your phone carrier", class: "select2"} %>

但我仍然无法弄清楚如何将电话号码剥离为 5555555555 并将 :phone 字段与 :carrier 对象自动合并到 :sms 字段中(最好是客户端)

【问题讨论】:

    标签: javascript jquery ruby-on-rails-3 forms rails-activerecord


    【解决方案1】:

    在进行了大量研究并打破了一些东西之后,我想出了以下方法来完成这项工作。模型和表格只显示我所做的更改,而不是完整的表格或模型。

    表格

    <%= f.label 'Cell_Phone'%>
    <%= f.text_field :phone, placeholder: "xxx-xxx-xxxx", required: true %>
    <%= f.label :carrier, "SMS Notifications", class: "control-label" %>
    <%= f.select :carrier, phone_carriers.map{ |k, v| [k, v] }, {include_blank: true}, {placeholder: "Select your phone carrier", class: "select2"} %>
    <%= f.hidden_field :sms %>
    

    型号

    attr_accessible :carrier
    attr_accessor :carrier
    

    咖啡脚本

    $ ->
      $("#person_carrier").on "change", update_sms_address
      $("#person_phone").on "keyup", update_sms_address
      update_sms_address
    
    update_sms_address = ->
        digits  = $("#person_phone").val().match(/\d+/g)
        phone   = digits.join("") if digits
        carrier = $("#person_carrier").val()
    
        if phone? && phone.length == 10 && carrier
          sms = phone + carrier
          $("#person_sms").val(sms)
          $("#person-sms-number").html(sms)
        else if !carrier
          $("#person_sms").val("")
          $("#person-sms-number").html("Choose a carrier to receive SMS notifications")
        else
          $("#person_sms").val("")
          $("#person-sms-number").html("Invalid phone number")
    

    当输入格式为 281-444-4444 的电话号码时,这似乎有效,因为它会将号码剥离并将其与运营商数组中的值连接起来,并适当地设置隐藏的 :sms 字段。

    我现在唯一的问题是,因为我正在为承运人使用虚拟属性,如果我再次编辑此人,它不会保留承运人选择并将其留空。如果我在不更改任何信息的情况下提交表单,它将保留 :sms 字段,但它可能会令人困惑,因为 :carrier 不是数据库记住的实际字段,而是一个虚拟属性。

    有没有更好的方法来做到这一点?

    【讨论】:

    • 为什么运营商不是持久化字段?如果下次需要记住,请为它创建一个数据库列。
    • 此外,carrier 字段为空白,因为 person.carrier 为空白——它返回 @carrier 的默认值。如果您定义它,该字段将显示方法返回的任何内容:def carrier; sms.split('@')[1]; end。您甚至可能希望在 after_find 块中执行此操作,因此只需计算一次:after_find do; @carrier = sms.split('@')[1]; end
    【解决方案2】:

    如果你使用标准的 javascript 字符串库,不会是这样的

    function prepare(str){
      str2 = str.replace("(","").replace(")","").replace("-","")
      carrier = getCarrier //assuming this implemented by you somewhere 
      return (st2.concat(carrier))
    }
    

    【讨论】:

    • 我想它可以工作。但我真的需要弄清楚如何不仅去除任何格式的数量,还要将其与载体字段连接起来,并通过 JS/Jquery 自动填充 sms 字段。
    【解决方案3】:

    我将首先创建一个运营商表:

    rails generate model Carrier name:string email_domain:string
    

    并通过将以下内容添加到迁移中来在 Person 模型中引用它:

    change_table :people do |t|
      t.references :carrier
    end
    add_index :people, :carrier_id
    

    以下是您的人员模型:

    belongs_to :carrier
    validates_presence_of :carrier
    
    def sms
      carrier ? "#{phone}@#{carrier.email_domain}"
    end
    def phone_with_dashes
      "#{phone[0..2]}-#{phone[3..5]}-#{phone[6..9]}"
    end
    def phone_with_dashes=(_phone_with_dashes)
      self.phone = _phone_with_dashes.gsub(/-/ ,'')
    end
    

    现在,你的观点(我将把格式留给你):

    Phone: <%= f.phone_field :phone_with_dashes %>
    Carrier: <%= f.collection_select :carrier_id, Carrier.all, :id, :name %>
    <div id='person-sms-number'>
      <%= f.object.sms %>
    </div>
    

    最后,Coffeescript:这里唯一需要改变的是您不再需要“#person_sms”输入,因为您不再直接保存值 - 您是从其他字段动态生成的。

    【讨论】:

      猜你喜欢
      • 2017-11-18
      • 2011-02-18
      • 1970-01-01
      • 2013-05-07
      • 2018-08-09
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多