【问题标题】:Using Rails model method to fetch and return value使用 Rails 模型方法获取和返回值
【发布时间】:2018-06-05 13:09:30
【问题描述】:

问题

我目前在我的models/listing.rb 中有一个方法,它的方法如下:

 def self.lookup_info(val)
   # Fetch some data from the internet
   return{ price: value1, title: value2, isbn: val }
 end

当用户在创建新列表时将val 插入views/listings/_form.html.erb 时,我想调用lookup_info 并让它填写表单的其余部分,如果返回结果(不是零)。

设置

控制器/listings_controller.rb

def new
  @listing = Listing.new
end

views/listings/new.html.erb

<%= render 'form', listing: @listing %>

views/listings/_form.html.erb(我在实际代码中使用了 div 标签,但为简单起见不包括在下面)

<%= form_for(@listing, :html => {class: "form-horizontal" , role: "form"}) do |f| %>
    <%= f.label :isbn, "ISBN" %>
    <%= f.text_field :isbn , class: "form-control" , id: "isbn_field", placeholder: "ISBN (10 or 13 digits - no dashes)", autofocus: true %>
    <%= f.label :price, "Price" %>
    <%= f.text_field :price , class: "form-control" , id: "price_field", placeholder: "Price" %>
    <%= f.label :title, "URL" %>
    <%= f.text_field :title , class: "form-control" , id: "title_field", placeholder: "Title" %>
    <%= f.submit class: "btn btn-primary btn-lg" %>
<% end %>

当用户输入 users_isbn 时,我需要什么 javascript 和 rails 来更新 _form.html.erb,我调用 lookup_info(users_isbn),然后获取更新的部分,以便将字段的值设置为结果。

响应示例:

<%= form_for(@listing, :html => {class: "form-horizontal" , role: "form"}) do |f| %>
        <%= f.label :isbn, "ISBN" %>
        <%= f.text_field :isbn , class: "form-control" , id: "isbn_field", placeholder: "ISBN (10 or 13 digits - no dashes)", value: lookup_info(users_isbn)[:isbn] autofocus: true %>
        <%= f.label :price, "Price" %>
        <%= f.text_field :price , class: "form-control" , id: "price_field", placeholder: "Price", value: lookup_info(users_isbn)[:price] %>
... <!-- Same idea for title -->
<% end %>

当前开始使用 Javascript

这是我目前所拥有的:

_form.js.erb(不确定这是否是 js 文件的正确名称)

var isbnField = document.getElementById('#isbn_field').value;
if (isbnField.length == (10 || 13)){
  var ajaxResponse = $.ajax({
        url: "listings/lookup",
        type: 'GET',
        data: {isbn: $('#isbn_field').val()}
      });
      ajaxResponse.success(function(){
        alert("Success"); # I would actually want to <%= j render #name of form partial with values %>
      });
      ajaxResponse.error(function(){
         alert("Could not find that ISBN");
      });
}

【问题讨论】:

    标签: ruby-on-rails ajax methods


    【解决方案1】:

    我建议这样做。

    listings_controller.rb

    # your new action
    
    # your search action
    def search
      @foo = lookup_info(val) 
      # You might have to change this line to something like
      # self.lookup_info(val) since I can't see the exact application of
      # your lookup_info method. But the idea is you would want to put
      # the return values into your @foo.
      if @foo
        respond_to { |format| format.js { render listings/success }
      else
        respond_to { |format| format.js {render listings/failure }
      end
    end
    

    控制器动作说明: 您的表单将提交给控制器操作search。如果@foo 有效,这意味着如果搜索成功,它将渲染我们将创建的成功的局部视图,否则我们将渲染一个视图来处理失败的表单提交(假设您需要它)。

    routes.rb

    get "my-search-url", to: "listings#search", as: "my_search_url"
    # you can set your own route names
    # i assume your form is a get instead of post action
    

    现在为您的表单,将其更改为form_with

    <%= form_with(url: my_search_url_path) do |f| %>
    

    如果您使用的是 Rails 4 而不是 Rails 5,则不能使用 form_with,而必须使用 remote: true 来为您处理 ajax 请求。

    最后,在您看来,您需要这两个组件,js.erb 和部分

    success.js.erb

    $("#holder-for-search").html("<%= j render partial: 'listings/success' %>");
    $("#bigger-holder-for-search").fadeIn("1000");
    
    # note that the file name has to be the same as what your respond_to is rendering in your search action
    # also remember to create a failure.js.erb too to handle the failed search
    

    _success.html.erb

    # render what you want to show if search is successful
    

    在您的new.html.erb 或显示表单的任何位置,只需将您的相关div 与正确的ID 标签(例如#holder-for-search)联系起来

    <div id="bigger-holder-for-search" style="display:none;">
      <div id="holder-for-search">
      </div>
    </div>
    
    // and you can consider fading everything else out to fade in your search response
    

    总而言之,要重现 AJAX 响应,您需要 4 个组件:

    1) 在你的控制器动作中,你需要respond_to { |format| format.js }

    2) 您需要在您的视图中有一个对应的js.erb(必须完全像控制器操作或respond_to 响应一样命名)

    3) 你的js.erb要渲染的部分

    4) remote: true 操作。如果是链接,则将其包含在链接中,如果是表单,则将其包含在表单中。在 rails 5 中,form_with 表示 remote: true,因此您无需显式输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多