Ruby On Rails:如何在ajax请求中从数据库中检索数据

时间:2016-01-05 17:58:49

标签: jquery ruby-on-rails ruby ajax

我有一个表单,在输入字段中键入时,我需要获取所有类别 其中包含类别表中的关键字。

我有两个控制器即。书籍和类别。

主要目标是添加一本书并选择一个类别。

我需要使用ajax来做到这一点。

我已经尝试了很多。但它们都不起作用。

我已经包含了jquery和所有需要的脚本。但仍然是它的表现。

任何人都可以帮我这个吗?

JQUERY

$('#book_search').keyup(function(){

                $.ajax({
                    type:"GET",
                    url:"books/new",
                    dataType:"json",
                    data: {keyword: '$("input[name'search']").val()},
                    success:function(result){
                        alert(result);
                    }
                })
            })

HTML

<%= simple_form_for :book, url: books_path do |f| %>
                <p> <%= f.label :name %> <%= f.text_field :name %> </p>
                <p> <%= f.input :category, collection: @categories, prompt: "Select Category" %></p>
                <p> <%= f.label :search %> <%= f.text_field :search %> </p>
                <p> <%= f.submit %></p>
            <% end %>



class BooksController < ApplicationController
    def index
        @books = Book.all
        @categories = Category.all
    end
    def new
        @categories = Category.all
    end

    def create
        @book = Book.new(book_params)        
        @book.save
        redirect_to @book
    end

    def show
        @book = Book.find(params[:id])
        @categories = Category.all
    end

    def show_categories
        @category = Category.find(params[:id])
    end

    private
        def book_params
            params.require(:book).permit(:name, :category)
        end
end

1 个答案:

答案 0 :(得分:3)

有很多库实现自动完成,包括2个最流行的自动完成和预先输入。

然而,显然每个库都是额外的开销,所以如果你想自己实现它,你当然可以。

需要考虑的一些事项:

  1. 请求的URL - 假设在这种情况下您不关心hte书籍,并且实际上只想要所有可能匹配的类别的列表,最好调用类别控制器并相应地放置您的代码。
  2. 您需要返回一个列表以便用户可以选择,但您不需要将该列表传递给控制器​​,因此category_id的隐藏字段是个好主意,这样您就可以忽略所有强大的内容params已经过滤掉了,只保留好东西。
  3. jBuilder是你的朋友。它可以让你随心所欲地布置JSON,而不会让你的控制器蒙上阴影。在这种情况下,它并不是绝对必要的,因为您只需要一个标签字段和一个id字段,但我会把它扔进去。
  4. 由于您在标准控制器调用中使用@categories,我会犹豫是否使用相同的实例变量来返回搜索结果,因此我将其命名为不同。
  5. 就我看来,原始示例中的下拉框是不必要的,因为无序列表与较少的代码一样好。
  6. 鉴于此,您可以在视图(表单)中执行类似的操作

    视图

    <div id="book_create">
        <%= simple_form_for :book, url: books_path do |f|  %>
            <%= f.input :name  %>
            <%= f.input :category_id, as: :hidden %>
            <%= f.input :category_search, as: :string, input_html: {class: "book_search"} , autocomplete: false %>
            <div id="cat_search"></div>
            <%= f.submit %>
        <% end %>
    </div>
    <style>
        #categories { width: 200px; max-height: 220px; overflow: scroll; box-shadow: 1px 1px 4px rgba(158, 158, 158, 0.43); list-style: none; padding: 0; }
        #categories li:nth-of-type(odd) { background-color: rgb(238, 247, 255); }
        #categories li { cursor: pointer; }
    </style>
    

    简单的css包括在内。

    的Javascript

    $('.book_search').keyup(function(){
        var q = $(this).val();
        $.ajax({
            type: "GET",
            url: "/categories/search",
            dataType: "json",
            data: {'keyword': q},
            success: function(result){
                $("#categories").remove();
                $("#cat_search").after('<ul id="categories"></ul>');
                render = true;
                $("#categories").on("click", "li", function(){
                    $("#book_category_id").val($(this).data('id'));
                    $(".book_search").val($(this).text());
                    $("#categories").remove();
                });
                for(term in result){
                    render = false;
                    $("#categories").append("<li data-id="+result[term].id+">" + result[term].keyword + "</li>");
                }
            }
        })
    });
    

    这个JS真的没有轨道​​魔法,它只是简单的jQuery。您获取用户输入并使用用户输入作为查询来调用URL,如果返回查询,则删除任何先前的显示列表,然后为具有所有可能结果的用户构建显示列表(ul)。单击您选择的结果会做两件事,它是a。)从我们从结果集中注入的数据属性中添加id和b。)清除用户键入的输入字段,将其替换为所选结果的全名

    控制器

    class CategoriesController < ApplicationController
        before_action :set_category, only: [:show, :edit, :update, :destroy]
        respond_to :json, :html
        def search
            @cat_search_results = Category.where("keyword LIKE LOWER(?)", "%#{params[:keyword].downcase}%")
            respond_with(@cat_search_results, :include => :status)
        end
    end
    

    Jbuilder的

    #/categories/search.json.jbuilder
    json.array!(@cat_search_results) do |category|
        json.extract! category, :id, :keyword
    end
    

    路线

    resources categories do
        collection do
            get :search
        end
    end