使用Rails模型方法获取并返回值

时间:2017-12-23 01:16:01

标签: ruby-on-rails ajax methods

问题

我目前在我的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并填写表单的其余部分(如果结果)(不是nil)归还。

设置

控制器/ listings_controller.rb

def new
  @listing = Listing.new
end

视图/列表/ 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");
      });
}

1 个答案:

答案 0 :(得分: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 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,因此您无需明确键入该内容。