使用acts_as_taggable_on和jQuery自动完成时指定标记上下文

时间:2014-09-25 21:35:26

标签: ruby-on-rails-4 jquery-autocomplete acts-as-taggable-on

我正在使用gems https://github.com/mbleigh/acts-as-taggable-onhttps://github.com/crowdint/rails3-jquery-autocomplete在Rails 4应用上实现标记。

我有一个名为Question的模型,其中包含两个不同的标记类别(上下文)::topics:courses。我似乎无法解决的问题是过滤标签以进行自动完成,以便只向用户提供来自适当上下文的标签。否则,标签和自动完成的基本功能可以正常工作,这意味着用户可以键入给定标签的前三个字母,并提供一个标签列表供选择(只是不按上下文过滤)。

question.rb

acts_as_taggable_on   :topics, :courses

questions_controller.rb

autocomplete :topic, :name, :class_name => 'ActsAsTaggableOn::Tag'
autocomplete :course, :name, :class_name => 'ActsAsTaggableOn::Tag'

注意:我尝试将:class_name更改为ActsAsTaggableOn::CourseActsAsTaggableOn::Topic,但收到了(有些预期)错误:NameError (uninitialized constant ActsAsTaggableOn::Topic):

问题/ _form.html.erb

<%= f.autocomplete_field :course_list, autocomplete_course_name_questions_path, :"data-delimiter" => ', ' %>
<%= f.autocomplete_field :topic_list, autocomplete_topic_name_questions_path, :"data-delimiter" => ', ' %>

配置/ routes.rb中

resources :questions do
  get :autocomplete_topic_name, :on => :collection
  get :autocomplete_course_name, :on => :collection
end

的Gemfile

gem 'acts-as-taggable-on', '~> 3.4.1'
gem 'rails3-jquery-autocomplete', '~> 1.0.14'

我应该考虑放弃rails3-jquery-autocomplete并直接使用jQuery UI小部件吗?是否有一种方法可以使用:scopes中的rails3-jquery-autocomplete选项来实现所需的结果?我是否只是通过在同一模型中使用不同的标签上下文以错误的方式解决问题?也许覆盖autocomplete_...控制器中的Questions方法来过滤正确的标签?任何和所有的想法都表示赞赏。提前谢谢。

1 个答案:

答案 0 :(得分:2)

希望这有助于其他人,这就是我解决这个问题的方法。

首先,我用jQuery Tokeninput替换了jQuery自动完成,位于:http://loopj.com/jquery-tokeninput/。我大多遵循本网站上的食谱:http://bloginius.com/blog/2013/12/31/how-integrate-acts-as-taggable-on-with-jquery-token-input-with-rails-3/。我怀疑我的解决方案不如作者那么有效或优雅,但我不得不调整它以使用Rails 4并使用两个“上下文”(:topics:courses)而不是{{1 }}

以下是代码:

<强>资产/ Javascript角/ questions.js.coffee

:tags

<强>控制器/ questions_controller.rb

jQuery ->
  $('#question_topic_list_tokens').tokenInput '/questions/topics.json',
    theme: 'facebook'
    minChars: 3
    allowCustomEntry: false
    preventDuplicates: true
    prePopulate: $('#question_topic_list_tokens').data('load')

jQuery ->
  $('#question_course_list_tokens').tokenInput '/questions/courses.json',
  theme: 'facebook'
  minChars: 3
  allowCustomEntry: false
  preventDuplicates: true
  prePopulate: $('#question_course_list_tokens').data('load')

<强> qmodels / question.rb

before_filter :find_topic_tags, only: [:new, :create, :edit, :update]
before_filter :find_course_tags, only: [:new, :create, :edit, :update]

def topics
  topics = Question.topic_counts.by_tag_name(params[:q]).map{|t| {id: t.name, name: t.name }}
  respond_to do |format|
    format.json { render json: topics }
  end
end

def courses
  courses = Question.course_counts.by_tag_name(params[:q]).map{|t| {id: t.name, name: t.name }}
  respond_to do |format|
    format.json { render json: courses }
  end
end

def question_params
  params.require(:question).permit(..., :topic_list_tokens, :course_list_tokens, ...)
end

def find_topic_tags
  @question_topics = params[:id].present? ? Question.find(params[:id]).topics.map{|t| {id: t.name, name: t.name }} : []
end

def find_course_tags
  @question_courses = params[:id].present? ? Question.find(params[:id]).courses.map{|t| {id: t.name, name: t.name }} : []
end

<强>视图/问题/ _form.html.erb

acts_as_taggable_on   :topics, :courses

attr_reader   :course_list_tokens, :topic_list_tokens

def topic_list_tokens=(tokens)
  self.topic_list = tokens.gsub("'", "")
end

def course_list_tokens=(tokens)
  self.course_list = tokens.gsub("'", "")
end

<强>配置/初始化/ acts_as_taggable_on.rb

    <div class="form-group">
        <div class="col-md-3 control-label">
          <%= f.label :course_list_tokens, "course tags (separated by commas)" %><br/>
        </div>
        <div class="controls col-md-4">
          <%= f.text_field :course_list_tokens, data: {load: @question_courses} %>
        </div>
        <div class="col-md-3 text-muted">(optional)</div>
    </div>

    <div class="form-group">
        <div class="col-md-3 control-label">
              <%= f.label :topic_list_tokens, "topic tags (separated by commas)" %><br/>
        </div>
        <div class="controls col-md-4">
          <%= f.text_field :topic_list_tokens, data: {load: @question_topics} %>
        </div>
        <div class="col-md-3 text-muted">(optional)</div>
    </div>

<强>配置/ routes.rb中

ActsAsTaggableOn::Tag.send(:include, <YOUR APP>::TagExtend)

<强> LIB / tag_extend.rb

resources :questions do
  collection do
    get :topics, as: :topics
    get :courses, as: :courses
  end
end