2016-09-12 1 views
0

Lorsque j'exécute la fonctionnalité de saisie semi-automatique dans la console rails, cela fonctionne. Mais quand je tape dans le champ de recherche sur le navigateur, il n'y a pas de menu déroulant montrant les résultats de saisie semi-automatique. Voici mon code. Toute aide est appréciée. Je suis nouveau à tout cela, et enseigne moi-même en faisant des recherches.RUBY ON RAILS: Pourquoi la saisie semi-automatique n'est-elle pas typée en utilisant searchkick/elasticsearch?

routes.rb

Rails.application.routes.draw do 

    resources :search_suggestions 
    devise_for :users 

    resources :posts do 

    collection do 
    get 'search' 
    get 'autocomplete' 
    end 

    resources :reviews, except: [:show, :index] 

end 

root to: 'posts#index' 
# For details on the DSL available within this file, see  http://guides.rubyonrails.org/routing.html 
end 

post.rb

class Post < ApplicationRecord 
belongs_to :user 
has_many :reviews, dependent: :destroy 
searchkick autocomplete: [:title] 
has_attached_file :image, styles: { medium: "300x300#"} 
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/ 

end 

posts_controller.rb

class PostsController < ApplicationController 
before_action :set_post, only: [:show, :edit, :update, :destroy] 
before_action :authenticate_user!, except: [:index, :show] 


def search 
if params[:search].present? 
    @posts = Post.search(params[:search]) 
else 
    @posts = Post.all.order("created_at DESC") 
end 
end 

def autocomplete 
    render json: Post.search(params[:search], autocomplete: true, limit: 10).map(&:title) 
end 

# GET /posts 
# GET /posts.json 
def index 
    @posts = Post.all.order("created_at DESC") 
end 

# GET /posts/1 
# GET /posts/1.json 
def show 
@reviews = Review.where(post_id: @post.id).order("created_at DESC") 

if @reviews.blank? 
    @avg_review = 0 
else 
    @avg_review = @reviews.average(:rating).round(2) 
end 

end 

# GET /posts/new 
def new 
@post = current_user.posts.build 
end 

    # GET /posts/1/edit 
def edit 
end 

    # POST /posts 
    # POST /posts.json 
def create 
@post = current_user.posts.build(post_params) 

respond_to do |format| 
    if @post.save 
    format.html { redirect_to @post, notice: 'Post was successfully created.' } 
    format.json { render :show, status: :created, location: @post } 
    else 
    format.html { render :new } 
    format.json { render json: @post.errors, status: :unprocessable_entity } 
    end 
end 
end 

# PATCH/PUT /posts/1 
# PATCH/PUT /posts/1.json 
def update 
respond_to do |format| 
    if @post.update(post_params) 
    format.html { redirect_to @post, notice: 'Post was successfully updated.' } 
    format.json { render :show, status: :ok, location: @post } 
    else 
    format.html { render :edit } 
    format.json { render json: @post.errors, status: :unprocessable_entity } 
    end 
end 
end 

    # DELETE /posts/1 
    # DELETE /posts/1.json 
def destroy 
@post.destroy 
respond_to do |format| 
    format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' } 
    format.json { head :no_content } 
end 
end 

private 
# Use callbacks to share common setup or constraints between actions. 
def set_post 
    @post = Post.find(params[:id]) 
end 

# Never trust parameters from the scary internet, only allow the white list through. 
def post_params 
    params.require(:post).permit(:title, :content, :image) 
end 
end 

posts.coffee

$("#search").typeahead({ 
name: "post", 
remote: "/posts/autocomplete?search=%SEARCH" 
}); 

autocomplete.haml

= render 'layouts/header' 

_header.haml

%nav.navbar.navbar-default.navbar-fixed-top 
.container-fluid 
    .navbar-header 
     %button.navbar-toggle.collapsed(type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false") 
      %span.sr-only Toggle navigation 
      %span.icon-bar 
      %span.icon-bar 
      %span.icon-bar 

     = link_to "Brand", root_path, class: "navbar-brand" 

    .collapse.navbar-collapse#bs-example-navbar-collapse-1 
     %ul.nav.navbar-nav.navbar-right 
      - if user_signed_in? 

       %li 
        = link_to current_user.username, edit_user_registration_path 

       %li 
        = link_to 'new', new_post_path 

       %li 
        = link_to '', destroy_user_session_path, :method => :delete, data: { confirm: 'Are you sure you want to log out?' }, class: " glyphicon glyphicon-off" 

      - else 
       %li 
        = link_to "Sign Up", new_user_registration_path 
       %li 
        = link_to "Sign In", new_user_session_path 

     = form_tag search_posts_path, method: :get, class: "navbar-form navbar-left", role: "search" do 
      .input-group(style="max-width:181px;") 
       = text_field_tag :search, params[:search], placeholder: "search", id: "search", name: "search", class: "form-control", autocomplete: "off" 
       %span.input-group-btn 
        %button.glyphicon.glyphicon-search.btn.btn-default(type="button") 


%script 
    $('.glyphicon-search').click(function(){ $('.navbar-left').submit()}); 
+0

Je ne suis pas grand sur coffeescript, mais n'est pas votre postscoffee coffeescript invalide? – BigRon

Répondre

0

Votre fichier est posts.coffee javascript pas coffeescript.

Vous pouvez brancher javascript sur this converter pour obtenir cette sortie coffeescript:

$('#search').typeahead 
    name: 'post' 
    remote: '/posts/autocomplete?search=%SEARCH' 

Autres notes

  • les espaces et tirets sur coffeescript sont critiques pour les règles de syntaxe (qui est pourquoi je ne l'utilise pas). Chaque fois que je l'utilise, je le copie directement du convertisseur afin de ne pas endommager l'espacement et les retraits.

  • votre autre option serait de changer posts.coffee-posts.js afin que vous puissiez garder votre javascript

  • selon que vous utilisez le jquery-turbolinks gem vous devez également ajouter le contrôle $(document).ready avant votre fonction typeahead fonctionnera

    votre javascript deviendrait:

    $(function() { 
        $("#search").typeahead({ 
        name: "post", 
        remote: "/posts/autocomplete?search=%SEARCH" 
        }); 
    }); 
    

    ou l'équivalent coffeescript:

    $ -> 
        $('#search').typeahead 
        name: 'post' 
        remote: '/posts/autocomplete?search=%SEARCH' 
        return 
    
0

S'il vous plaît lire attentivement ce code et voir mes modifications, je reste la partie pertinente (tout semble correct)

posts_controller.rb

def autocomplete 
    render json: Post.search(params[:search], autocomplete: true, limit: 10).map(|post|{title: post.title}) 
end 

messages.Je ne sais pas pourquoi cette syntaxe bizarre typeahead est nécessaire mais cela fonctionne. Voyez comment vous devriez former votre réponse json et comment est la bonne façon de le lire sur le client.

vous devriez consulter ce guide merveilleux: https://rubyplus.com/articles/4031-Autocomplete-using-Typeahead-and-Searchkick-in-Rails-5

espère que cela aide.