Hey guys I'm new to rails and try to do something I never did before. First I now Rails have the gems acts_as_taggable but I try it and didn't work for me maybe need to learn how to install him(have already install acts_as_votable).
So this is my question, I want to show related articles(with tag) for each article show. And also want to put the article.count by tag into my label.
article.rb
class Article < ApplicationRecord
acts_as_votable
belongs_to :category
belongs_to :user
has_many :taggings
has_many :tags, through: :taggings
def tag_list
self.tags.collect do |tag|
tag.name
end.join(", ")
end
def tag_list=(tags_string)
tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
new_or_found_tags = tag_names.collect { |name| Tag.find_or_create_by(name: name) }
self.tags = new_or_found_tags
end
has_attached_file :image, styles: { front: "400x500>" ,medium: "700x500>", small: "350x250>" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
tag.rb
class Tag < ApplicationRecord
has_many :taggings
has_many :articles, through: :taggings
def to_s
name
end
end
tagging.rb
class Tagging < ApplicationRecord
belongs_to :article
belongs_to :tag
end
articles_controller.rb
class ArticlesController < ApplicationController
before_action :find_article, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
before_action :authenticate_user!, except: [:show, :index]
def index
if params[:category].blank?
@articles = Article.page(params[:page]).per(10).order('created_at DESC')
else
@category_id = Category.find_by(name: params[:category]).id
@articles = Article.where(category_id: @category_id).order("created_at DESC")
end
@tags = Tag.all
end
def show
# if params[:tag]
# @articles = Article.tagged_with(params[:tag])
# @tag = @articles
# end
end
def new
@article = current_user.articles.build
end
def create
@article = current_user.articles.build(article_params)
if @article.save
redirect_to @article
else
render 'new'
end
end
def edit
end
def update
if @article.update(article_params)
redirect_to @article
else
render 'edit'
end
end
def destroy
@artice.destroy
redirect_to root_path
end
def upvote
@article.upvote_by current_user
redirect_to :back
end
def downvote
@article.downvote_by current_user
redirect_to :back
end
private
def find_article
@article = Article.find(params[:id])
end
def article_params
params.require(:article).permit(:title, :content, :category_id, :image, :tag_list)
end
end
tags_controller.rb
class TagsController < ApplicationController
def show
@tag = Tag.find(params[:id])
end
end
And this is the show page want to show the related articles
articles/show.html.haml
.container
.row
.col-md-8.col-offset-2
%h1= @article.title
= image_tag @article.image.url(:medium)
%br/
- @article.tags.each do |tag|
%h4
%strong
%span.label.label-danger
%i.fa.fa-tag
= link_to tag.name, tag
= tag.name.count
.pull-right
- if @article.user == current_user
.btn-group
= link_to 'Edit', edit_article_path, class: "btn btn-default"
= link_to 'Delete', article_path, method: :delete, data: {confirm: 'Are you sure ?'}, class: 'btn btn-danger'
%hr/
%p
%i.fa.fa-pencil
%strong=@article.user.username
%button.btn.btn-primary
%i.fa.fa-hand-o-left
Follow
%p
%i.fa.fa-clock-o
%em= time_ago_in_words(@article.created_at) + ' ago'
%hr/
%p= simple_format(@article.content)
.row
.col-md-4
= link_to like_article_path(@article), method: :get, class: 'btn btn-primary data' do
%i.fa.fa-thumbs-o-up
= @article.get_upvotes.size
= link_to dislike_article_path(@article), method: :get, class: 'btn btn-danger data' do
%i.fa.fa-thumbs-o-down
= @article.get_downvotes.size
.col-md-6.pull-right
%h3 Share this Article
= social_share_button_tag
%hr/
= render 'layouts/disqus'
-# .col-md-3.col-md-offset-1
-# %h2.text-center Articles Related
-# %hr/
-# - if @article(params[:tag])
-# - @tag.articles.each do |article|
-# .thumbnail
-# = link_to image_tag(article.image.url(:small)), article
-# .caption
-# %h3.text-center= @article.title
-# = link_to 'Read', @article, class: "btn btn-danger"
-# .pull-right
-# %span.badge.upvote
-# %i.fa.fa-thumbs-o-up
-# = @article.get_upvotes.size
-# %span.badge.downvote
-# %i.fa.fa-thumbs-o-down
-# = @article.get_downvotes.size
You should look into acts-as-taggable-on. There's a lot of tutorials out there using it. I've tried it and it worked well. enter link description here
If you want to set up your own tag tables, you should look into many to many relationships: enter link description here
If you are trying to display related articles for each article and a count, and you set up everything correctly, it should be as easily as this:
(I am going to write in erb)
<% @articles.each do |article| %>
<%= article.title %>
<% article.tags.each do |tag| %>
Tag: <%= tag.to_s + "Related count: (#{tag.articles.count})" %>
Related articles:
<% tag.articles.each do |related_article| %>
<%= related_article.title %>
<% end %>
<% end %>
<% end %>