Rails 3 - which sql query for related tags - sql

I'm planning this feature now for a long time, and I just can't get started with it really, cause I don't know how to express it in code. Sometimes when I think I got it and know what I want, I suddenly get trapped again and everything stops making sense.
I have tags and taggings, so a has_many through relation with articles. You could call article.tags and tag.articles.
Now, each tag has their show page, basically like stackoverflow. And on this show site I want to list related tags, among others. My approach to these related tags is, that it should be those tags, which most often are tagged as well, at an article, which is tagged with the show tag. I hope this makes some sense.
Example: I'm on /tags/obama, so the related tags should be those that most often are used at articles, that include the tag obama. If I had 4 articles, and 3 of them included 'obama' and all of those 3 as well included the tag 'united_states' for example, then the most related tag to tag 'obama' would be 'united_states'. Sorry if I'm wordy..
I'm not even sure, if this is the best approach to find related tags, but this idea works fine for me. However, I can't implement it.
First I would need to fetch all articles, that include the show tag. So tag.articles. But what's the next step?
tag.articles.each do |article|
article.tags
... im just getting confused at this point.

I think the best way to solve this is to have a many to many relation between tags, so a tag can have many tags. Then in the relation between two tags, you store the count of how many instances they occur together.
You could also simply create a new tag-to-tag connection each time the tags occur in the same article. This will however create some redundancy in the database.
If you do not want to introduce another table, you can get this to work the way you started, except it might be very slow with even a fairly small amount of tags. But here is how I would have done this, if you can not make a Tag-to-tag connection:
hash_storage = Hash.new(0) #0 is the default value
tag.articles.each do |article|
if article.tags.each do |t|
#we now know that this tag "t" is in the same article as our original tag
if t!=tag #we don't care if t actually the same as our original tag
hash_storage[t]+=1
end
end
end
#Now, this is a bit messy, but we need to sort the hash.
ordered_tags = hash_storage.map{|k,v| [v,k]}.sort.reverse.map{|a,b| b} #there might be a smarter way of doing this.
ordered_tags.each do |t|
#do whatever. the tags should now be ordered by their relative frequence of occurrance together with the initial tag.
end
Hope this helps :)

Related

Can we reference tags in karate? [duplicate]

I'm wondering if you can use wildcard characters with tags to get all tagged scenarios/features that match a certain pattern.
For example, I've used 17 unique tags on many scenarios throughout many of my feature files. The pattern is "#jira=CIS-" followed by 4 numbers, like #jira=CIS-1234 and #jira=CIS-5678.
I'm hoping I can use a wildcard character or something that will find all of the matches for me.
I want to be able to exclude them from being run, when I run all of my features/scenarios.
I've tried the follow:
--tags ~#jira
--tags ~#jira*
--tags ~#jira=*
--tags ~#jira=
Unfortunately none have given my the results I wanted. I was only able to exclude them when I used the exact tag, ex. ~#jira=CIS-1234. It's not a good solution to have to add each single one (of the 17 different tags) to the command line. These tags can change frequently, with new ones being added and old ones being removed, plus it would make for one real long command.
Yes. First read this - there is this un-documented expression-language (based on JS) for advanced tag selction based on the #key=val1,val2 form: https://stackoverflow.com/a/67219165/143475
So you should be able to do this:
valuesFor('#jira').isPresent
And even (here s will be a string, on which you can even do JS regex if you know how):
valuesFor('#jira').isEach(s => s.startsWith('CIS-'))
Would be great to get your confirmation and then this thread itself can help others and we can add it to the docs at some point.

Show content based on whether the user has certain tag in Mailchimp

I went through the Merge Tags here and here, but couldn't figure out the syntax that would allow me to show content based on whether the user has certain Tag or not.
Help?
My goal in case it helps:
User subscribes, and is queued for a welcome mail one day later. In meantime that user may get tagged (my way of segmenting them), and so, the next day when that user receives the welcome mail, the content needs to be catered based on the tag that user got.
Got a response from their support saying
merge tags do not work with Tags just yet
here's the whole thing:
While we do have conditional merge tags available, I'm afraid we do
not have any that would work with Tags. To be transparent, Tags were
recently added a few months ago, and there are some features in our
application that has not updated to work with Tags just yet.
Because conditional merge tags do not work with tags yet, the best
option would be to create multiple automations and send them out based
on each tags. If you do it that way, you'll be able to target those in
specific tags with specific content
Dug a little deeper from the first link. There is another link Use Conditional Merge Tag Blocks which contained the below code:
Name
IF-ELSE
Definition
Use ELSE to indicate alternative content to display if the *|MERGE|* tag value is false.
Example
*|IF:MERGE|* content to display *|ELSE:|* alternative content to display *|END:IF|*
Name
ELSEIF
Definition
Use ELSEIF to specify a new *|MERGE|* tag to be matched against if the first *|MERGE|* tag value is false.
Example
*|IF:TRANSACTIONS >= 20|* Enjoy this 40% off coupon! *|COUPON40|*
*|ELSEIF:TRANSACTIONS >= 10|* Enjoy this 20% off coupon! *|COUPON20|*
*|ELSE:|* Enjoy this 10% off coupon! *|COUPON10|* *|END:IF|*
More examples with definitions can be found here.
Hope this is the answer you were after.

Middleman Blog: How do I get a count of articles?

I'm trying to return a string of the total count of items in a Middleman blog. (I'm currently using 3 on a site).
The closest I've come to getting the count is including = i in a loop, in which the results went from 0 to 34. So I know one particular blog has 35 items but I can't get that value on its own.
It feels like I should be able to do something like:
def get_articles_count(blogName)
data.blog(blogName).articles.count
end
= get_articles_count('posts')
Bonus begging: I'd love to know how I could've tracked down the answer, if possible. I'm missing something and I'd love to know where I should be looking. I've been referencing the local sitemap data http://localhost:4567/__middleman/sitemap, the MM docs, and the MM blog docs, but I can't decipher if an item in a blog is a page or an article. I only use article in my example because that's what the loops require for displaying post information.
It turns out that it's incredibly simple
= blog.articles.count
It turns out that it's so simple...
= blog.articles.count

Mongoid: Changing the order of documents in an embeds_many relation

I have a mongoid document which embeds other documents with a relation like
this:
embeds_many :blocks
Creating new blocks works fine, but I cannot manage to change the
order of existing embedded documents. For example I have three
embedded blocks and I want to move the last one to the first
position.What's the correct way to do that?
I had to deal with this with mongoid's recursively_embeds_many feature, but it's essentially the same. There's nothing wrong as far as I can tell with literally rewriting the document. Write a model method to do something like:
def reverse_blocks
reversed_blocks = blocks.to_a.reverse
blocks.clear
reversed_blocks.each do |b|
blocks.create b.attributes
end
save
end
That's not great code above, but it gives you an idea of how to do what you want to do. I'm not thrilled with having to go through that just to reorder stuff in an array, but there it is.
I think, that really correct way is make in your embedded docs field "weight" and query them with asc(:weight) or desc(:weight). You don't rely on the order of persisted non-embedded docs, so you shouldn't in embedded.
But if you urgently need to make this, your embedded docs in mongoid are just array, so you can do such way:
doc.embedded_docs = [doc.embedded_docs.last] + doc.embedded_docs[0..-2]

Creating tags on posts RAILS

I am making something that's like that autocomplete tags field for the posts on stackoverflow.com
I want to make it so that when you make a blog post, you can tag it with words in a database, similar to SO.
For the posts, it belongs_to_and_has_many tags
For the tags, it belongs_to_and_has_many posts
However it is a problem for me to do it on the same page because #post would be nil.
How can I implement this?
(If someone can give me the code for the stackoverflow ask question page that would be AWESOME)
I think the problem here is that it seems like you are asking two different questions. Please correct me if I'm wrong on this.
The first question is how you would implement the autocomplete feature to allow users to easily select from a pre-populated list of tags. To answer this, you might refer to spncrgr's answer above.
The second question is how to deal with associating these retrieved tags to the current post. For this you can add additional javascript functionality to your autocomplete solution. When a user selects which tag they want from the autocomplete field, you can do like StackOverflow does and add the tag to a list of tags in a single text field. These can be either space or comma delimited. When you submit the form to create the new post, you can parse this field into it's separate tags:
tags = params[:tags].split(' ')
You can then associate these tags to the model in the Post#create action.
This may not help you at all (or you may have already seen it), but here's a link to a Railscasts' episode on auto-complete:
http://railscasts.com/episodes/102-auto-complete-association
I know it helped me when trying to do something similar.
HTH
It looks for me like you want to generate tags automatically.
You could create
class Post
before_save :create_tags
private
def create_tags
# get your tags somehow
self.tags << Tag.new(:text=>"...")
end
end
method in models/post.rb and build them there.
If you want to search among existing tags for your auto-suggest, you should have it match from Tag.all, as that won't be nil, just as you would collect a group of objects in a select drop down. Not sure about the code for auto-complete, but the tags should be in the Tag table.