Skip to content

Commit

Permalink
basic tag-based testing and tag aliasing
Browse files Browse the repository at this point in the history
odd i18n fix

new tests

complete tests for tag aliasing, start of implementation

basic tag wildcarding

tag parents and parent-of, limited wildcard parenting

reduced scope aliasing

tag aliasing progress

tag aliasing, completed?

tag aliasing final fix

remove echoed statement

fix for rich editor template

html cleanup
  • Loading branch information
jywarren committed Oct 21, 2016
1 parent dd720ca commit eff8a44
Show file tree
Hide file tree
Showing 15 changed files with 373 additions and 58 deletions.
4 changes: 2 additions & 2 deletions PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Make sure these boxes are checked before your pull request is ready to be reviewed and merged. Thanks!

* [ ] All tests pass -- `rake test:all`
* [ ] all tests pass -- `rake test:all`
* [ ] code is in uniquely-named feature branch, and has been rebased on top of latest master (especially if you've been asked to make additional changes)
* [ ] pull request are descriptively named
* [ ] pull request is descriptively named with #number reference back to original issue
* [ ] if possible, multiple commits squashed if they're smaller changes
* [ ] reviewed/confirmed/tested by another contributor or maintainer
* [ ] `schema.rb.example` has been updated if any database migrations were added
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/tag_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ def show
if params[:id][-1..-1] == "*" # wildcard tags
@wildcard = true
@tags = DrupalTag.where('name LIKE (?)', params[:id][0..-2] + '%')
nodes = DrupalNode.where(:status => 1, :type => node_type)
nodes = DrupalNode.where(status: 1, type: node_type)
.includes(:drupal_node_revision, :drupal_tag)
.where('term_data.name LIKE (?)', params[:id][0..-2] + '%')
.where('term_data.name LIKE (?) OR term_data.parent LIKE (?)', params[:id][0..-2] + '%', params[:id][0..-2] + '%')
.page(params[:page])
.order("node_revisions.timestamp DESC")
else
@tags = DrupalTag.find_all_by_name params[:id]
nodes = DrupalNode.where(status: 1, type: node_type)
.includes(:drupal_node_revision, :drupal_tag)
.where('term_data.name = ?', params[:id])
.where('term_data.name = ? OR term_data.parent = ?', params[:id], params[:id])
.page(params[:page])
.order("node_revisions.timestamp DESC")
end
Expand Down
42 changes: 36 additions & 6 deletions app/models/drupal_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,9 @@ def response_count(key = 'response')
end

# power tags have "key:value" format, and should be searched with a "key:*" wildcard
def has_power_tag(tag)
def has_power_tag(key)
tids = DrupalTag.includes(:drupal_node_community_tag)
.where("community_tags.nid = ? AND name LIKE ?", self.id, tag+":%")
.where("community_tags.nid = ? AND name LIKE ?", self.id, key + ":%")
.collect(&:tid)
DrupalNodeCommunityTag.where('nid = ? AND tid IN (?)', self.id, tids).length > 0
end
Expand Down Expand Up @@ -400,10 +400,40 @@ def normal_tags
DrupalNodeCommunityTag.where('nid = ? AND tid NOT IN (?)', self.id, tids)
end

def has_tag(tag)
tids = DrupalTag.includes(:drupal_node_community_tag)
.where("community_tags.nid = ? AND name LIKE ?", self.id, tag)
.collect(&:tid)
# accests a tagname /or/ tagname ending in wildcard such as "tagnam*"
# also searches for other tags whose parent field matches given tagname,
# but not tags matching given tag's parent field
def has_tag(tagname)
tags = self.get_matching_tags_without_aliasing(tagname)
# search for tags with parent matching this
tags += DrupalTag.includes(:drupal_node_community_tag)
.where("community_tags.nid = ? AND parent LIKE ?", self.id, tagname)
# search for parent tag of this, if exists
#tag = DrupalTag.where(name: tagname).try(:first)
#if tag && tag.parent
# tags += DrupalTag.includes(:drupal_node_community_tag)
# .where("community_tags.nid = ? AND name LIKE ?", self.id, tag.parent)
#end
tids = tags.collect(&:tid).uniq
DrupalNodeCommunityTag.where('nid IN (?) AND tid IN (?)', self.id, tids).length > 0
end

# can return multiple DrupalTag records -- we don't yet hard-enforce uniqueness, but should soon
# then, this would just be replaced by DrupalTag.where(name: tagname).first
def get_matching_tags_without_aliasing(tagname)
tags = DrupalTag.includes(:drupal_node_community_tag)
.where("community_tags.nid = ? AND name LIKE ?", self.id, tagname)
# search for tags which end in wildcards
if tagname[-1] == '*'
tags += DrupalTag.includes(:drupal_node_community_tag)
.where("community_tags.nid = ? AND (name LIKE ? OR name LIKE ?)", self.id, tagname, tagname.gsub('*', '%'))
end
tags
end

def has_tag_without_aliasing(tagname)
tags = self.get_matching_tags_without_aliasing(tagname)
tids = tags.collect(&:tid).uniq
DrupalNodeCommunityTag.where('nid IN (?) AND tid IN (?)', self.id, tids).length > 0
end

Expand Down
77 changes: 54 additions & 23 deletions app/models/drupal_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ class DrupalTag < ActiveRecord::Base

# we're not really using the filter_by_type stuff here:
has_many :drupal_node, :through => :drupal_node_tag do
def filter_by_type(type,limit = 10)
find(:all, :conditions => {:status => 1, :type => type}, :limit => limit, :order => "created DESC")
def filter_by_type(type, limit = 10)
self.where(status: 1, type: type)
.limit(limit)
.order("created DESC")
end
end

Expand All @@ -19,7 +21,9 @@ def filter_by_type(type,limit = 10)
# also, we're not really using the filter_by_type stuff here:
has_many :drupal_node, :through => :drupal_node_community_tag do
def filter_by_type(type,limit = 10)
find(:all, :conditions => {:status => 1, :type => type}, :limit => limit, :order => "created DESC")
self.where(status: 1, type: type)
.limit(limit)
.order("created DESC")
end
end

Expand All @@ -32,17 +36,17 @@ def id
end

def run_count
self.count = DrupalNodeCommunityTag.where(:tid => self.tid).count
self.count = DrupalNodeCommunityTag.where(tid: self.tid).count
self.save
end

def subscriptions
self.tag_selection
end

# nodes this tag has been used on
# nodes this tag has been used on; no wildcards
def nodes
DrupalNode.where(nid: self.drupal_node_community_tag.collect(&:nid))
nodes = DrupalNode.where(nid: self.drupal_node_community_tag.collect(&:nid))
end

def is_community_tag(nid)
Expand All @@ -56,55 +60,82 @@ def belongs_to(current_user, nid)

# finds highest viewcount nodes
def self.find_top_nodes_by_type(tagname, type = "wiki", limit = 10)
DrupalNode.find_all_by_type type, :conditions => ['term_data.name = ?', tagname], :order => "node_counter.totalcount DESC", :limit => limit, :include => [:drupal_node_counter, :drupal_node_community_tag, :drupal_tag]
DrupalNode.where(type: type)
.where('term_data.name = ?', tagname)
.order("node_counter.totalcount DESC")
.limit(limit)
.include(:drupal_node_counter, :drupal_node_community_tag, :drupal_tag)
end

# finds recent nodes
# finds recent nodes - should drop "limit" and allow use of chainable .limit()
def self.find_nodes_by_type(tagnames, type = "note", limit = 10)
DrupalNode.where(status: 1, type: type)
nodes = DrupalNode.where(status: 1, type: type)
.includes(:drupal_node_revision, :drupal_tag)
.where('term_data.name IN (?)', tagnames)
# .where('term_data.name IN (?) OR term_data.parent in (?)', tagnames, tagnames) # greedily fetch children
tags = DrupalTag.where('term_data.name IN (?)', tagnames)
parents = DrupalNode.where(status: 1, type: type)
.includes(:drupal_node_revision, :drupal_tag)
.where('term_data.name IN (?)', tags.collect(&:parent))
DrupalNode.where('node.nid IN (?)', (nodes + parents).collect(&:nid))
.includes(:drupal_node_revision, :drupal_tag)
.where('term_data.name IN (?)', tagnames)
.order("node_revisions.timestamp DESC")
.limit(limit)
end

# just like find_nodes_by_type, but searches wiki pages, places, and tools
def self.find_pages(tagnames,limit = 10)
self.find_nodes_by_type(tagnames,['page','place','tool'],limit)
self.find_nodes_by_type(tagnames, ['page','place','tool'], limit)
end

def self.find_nodes_by_type_with_all_tags(tagnames,type = "note",limit = 10)
nids = false
def self.find_nodes_by_type_with_all_tags(tagnames, type = "note", limit = 10)
nids = []
tagnames.each do |tagname|
tids = DrupalTag.find(:all, :conditions => {:name => tagname}).collect(&:tid)
tag_nids = DrupalNodeCommunityTag.find(:all, :conditions => ["tid IN (?)",tids]).collect(&:nid)
nids = tag_nids if nids == false
nids = nids & tag_nids
#tids = DrupalTag.where('term_data.name IN (?) OR term_data.parent IN (?)', tagnames, tagnames) # greedily fetch children
tids = DrupalTag.where('term_data.name IN (?)', tagnames)
.collect(&:tid)
tag_nids = DrupalNodeCommunityTag.where("tid IN (?)", tids)
.collect(&:nid)
tag = DrupalTag.where(name: tagname).last
parents = DrupalNode.where(status: 1, type: type)
.includes(:drupal_node_revision, :drupal_tag)
.where('term_data.name LIKE ?', tag.parent)
nids += tag_nids + parents.collect(&:nid)
end
DrupalNode.find :all, :conditions => ["nid IN (?)",nids], :order => "nid DESC", :limit => limit
DrupalNode.where("nid IN (?)", nids)
.order("nid DESC")
.limit(limit)
end

def self.find_popular_notes(tagname,views = 20,limit = 10)
DrupalNode.find_all_by_type "note", :conditions => ['term_data.name = ? AND node_counter.totalcount > (?)', tagname, views], :order => "node.nid DESC", :limit => limit, :include => [:drupal_node_counter, :drupal_node_community_tag, :drupal_tag]
def self.find_popular_notes(tagname, views = 20, limit = 10)
DrupalNode.where(type: "note")
.where('term_data.name = ? AND node_counter.totalcount > (?)', tagname, views)
.order("node.nid DESC")
.limit(limit)
.include(:drupal_node_counter, :drupal_node_community_tag, :drupal_tag)
end

def self.exists?(tagname,nid)
DrupalNodeCommunityTag.find(:all, :conditions => ['nid = ? AND term_data.name = ?',nid,tagname], :joins => :drupal_tag).length != 0
DrupalNodeCommunityTag.where('nid = ? AND term_data.name = ?', nid, tagname)
.joins(:drupal_tag)
.length != 0
end

def self.is_powertag?(tagname)
!tagname.match(':').nil?
end

def self.follower_count(tagname)
TagSelection.joins(:drupal_tag).where(['term_data.name = ?',tagname]).count
TagSelection.joins(:drupal_tag)
.where('term_data.name = ?', tagname)
.count
end

def self.followers(tagname)
uids = TagSelection.joins(:drupal_tag)
.where('term_data.name = ?', tagname)
.collect(&:user_id)
DrupalUsers.where(['uid in (?)', uids])
DrupalUsers.where('uid in (?)', uids)
.collect(&:user)
end

Expand Down
2 changes: 1 addition & 1 deletion app/views/editor/post.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
<% end %>

<div class="form-group">
<input id="title" tabindex="1" name="title" class="form-control" placeholder="Title" value="<%= if @node then @node.title else params[:title] end %>"/>
<input id="title" tabindex="1" name="title" class="form-control" placeholder="<% if params[:template] == "question" %>Ask a question as specifically as possible<% else %>Title your post descriptively<% end %>" value="<%= if @node then @node.title else params[:title] end %>"/>
</div>

<input id="has_main_image" type="hidden" name="has_main_image" value="<% if @node && @node.main_image %>true<% end %>" />
Expand Down
11 changes: 9 additions & 2 deletions app/views/editor/rich.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<div class="col-xs-10">
<select class="form-control input-lg">
<option selected value="">a research note</option>
<option value="" <% if params[:tags].include?('question') %>selected='selected'<% end %>>a question or request</option>
<option value="" <% if params[:tags] && params[:tags].include?('question') %>selected='selected'<% end %>>a question or request</option>
<option value="">an event</option>
</select>
</div>
Expand Down Expand Up @@ -194,7 +194,14 @@
<% if params[:redirect] == 'question' %>
redirect: 'redirect',
<% end %>
format: 'publiclab'
format: 'publiclab',
richTextModule: {
authorsAutocomplete: false,
tagsAutocomplete: false
}
titleModule: {
suggestRelated: false
}
});

})();
Expand Down
2 changes: 1 addition & 1 deletion app/views/tag/contributors.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
</script>

<h3 style="margin-top:0;"><%= raw t('tag.contributors.contributors_for', :tag_name => params[:id]) %></h3>
<p><i><%= t('tag.contributors.contributions_over_past_year') %></p>
<p><i><%= t('tag.contributors.contributions_over_past_year') %></i></p>
<% if @users %><p><%= raw t('tag.contributors-index.notes_and_wiki_contributions', :users => @users.length || 0, :notes => @notes.length, :wikis => @wikis.length, :tag_name => params[:id]) %></p><% end %>

<% if current_user %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/tag/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</script>
<% end %>

<h3><%= raw t('tag.show.notes_tagged', :tag => params[:id]) %></h3>
<h3><%= raw t('tag.show.notes_tagged', :tag => params[:id]) %><% unless @tags.try(:first).try(:parent).nil? %> <small>parent: <%= @tags.first.parent %></small><% end %></h3>

<%= render :partial => "notes/format_toggle" if @node_type == "note" %>

Expand Down
2 changes: 1 addition & 1 deletion config/locales/views/tag/contributors-index/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ de:
follow: "Folgen"
people_watching_tag: "%[count} Personen beobachten Diesen Tag"
no_contributors_listed: "Keine Mitwirkenden aufgeführt."
write_research_note: "Ritus einer Research Note"
write_research_note: "Schreiben Sie eine Research Note"
20 changes: 20 additions & 0 deletions db/migrate/20161009024807_tag_parent.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class TagParent < ActiveRecord::Migration
def up
add_column :term_data, :parent, :string
add_index :term_data, :parent
drop_table :tags # clean up never-finished tag additions
end

def down
remove_index :term_data, :parent
remove_column :term_data, :parent
create_table :tags do |t|
t.string :key
t.string :value
t.string :user_id
t.string :type # note, wiki, profile, admin
t.text :body
t.timestamps
end
end
end
24 changes: 9 additions & 15 deletions db/schema.rb.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20160818201147) do
ActiveRecord::Schema.define(:version => 20161009024807) do

create_table "answer_selections", :force => true do |t|
t.integer "user_id"
Expand Down Expand Up @@ -176,13 +176,15 @@ ActiveRecord::Schema.define(:version => 20160818201147) do
create_table "location_tags", :force => true do |t|
t.integer "uid"
t.string "location"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.decimal "lat", :precision => 15, :scale => 10
t.decimal "lon", :precision => 15, :scale => 10
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.decimal "lat", :precision => 15, :scale => 10
t.decimal "lon", :precision => 15, :scale => 10
t.string "country"
t.string "state"
t.string "city"
t.integer "nid"
t.boolean "location_privacy"
end

create_table "node", :primary_key => "nid", :force => true do |t|
Expand Down Expand Up @@ -357,24 +359,16 @@ ActiveRecord::Schema.define(:version => 20160818201147) do

add_index "tag_selections", ["user_id", "tid"], :name => "index_tag_selections_on_user_id_and_tid", :unique => true

create_table "tags", :force => true do |t|
t.string "key"
t.string "value"
t.string "user_id"
t.string "type"
t.text "body"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end

create_table "term_data", :primary_key => "tid", :force => true do |t|
t.integer "vid", :default => 0, :null => false
t.string "name", :default => "", :null => false
t.text "description", :limit => 2147483647
t.integer "weight", :limit => 1, :default => 0, :null => false
t.integer "count"
t.string "parent"
end

add_index "term_data", ["parent"], :name => "index_term_data_on_parent"
add_index "term_data", ["vid", "name"], :name => "index_term_data_vid_name"
add_index "term_data", ["vid", "weight", "name"], :name => "index_vid_weight_name"

Expand Down
14 changes: 13 additions & 1 deletion test/fixtures/community_tags.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,16 @@ upgrade2:
tid: 11
uid: 9
nid: 16
date: Time.now
date: Time.now

spectrometer:
tid: 12
uid: 1
nid: 1
date: Time.now

activity-spectrometer:
tid: 14
uid: 1
nid: 1
date: Time.now
Loading

0 comments on commit eff8a44

Please sign in to comment.