两张关联表的实现方式 - tianlu1677/tianlu1677.github.io GitHub Wiki
假设我们这里有两个关联的表 Article和comments文章 因为要实现两个关联,嵌套,因此需要记录一下。
resources :articles do
get 'category_index', on: :collection
resources :comments do
member do
post 'useful'
post 'useless'
end
end
end
- category_index_articles_path GET /articles/category_index(.:format) articles#category_index
- useful_article_comment_path POST /articles/:article_id/comments/:id/useful(.:format) comments#useful
- useless_article_comment_path POST /articles/:article_id/comments/:id/useless(.:format) comments#useless
- article_comments_path GET /articles/:article_id/comments(.:format) comments#index
POST /articles/:article_id/comments(.:format) comments#create
- new_article_comment_path GET /articles/:article_id/comments/new(.:format) comments#new
- edit_article_comment_path GET /articles/:article_id/comments/:id/edit(.:format) comments#edit
- article_comment_path GET /articles/:article_id/comments/:id(.:format) comments#show
首先是article.rb
class Article
include Mongoid::Document
include Mongoid::Timestamps
field :title, type:String #文章标题
field :category, type:String #所属类别
field :content, type:String #内容
has_and_belongs_to_many :career_paths
has_many :comments
end
class Comment
include Mongoid::Document
include Mongoid::Timestamps
field :content, type: String
field :useful_count, type: Integer, default: 0
field :useless_count, type: Integer, default: 0
field :child_comments_count, type: Integer, default: 0
field :voted_user, type: Array, default: []
recursively_embeds_many # 自己嵌套自己
belongs_to :user
belongs_to :article
end
class ArticlesController < FrontResourceController
before_action :authenticate_user!, :forbidden_company_user!
layout "person"
def index
@articles = current_user.career_path.articles
end
def show
@article = Article.find(params[:id])
@comments = @article.comments
end
def category_index
@category_articles = Article.where(category: params[:category])
end
end
class CommentsController < FrontResourceController
before_action :authenticate_user!, :forbidden_company_user!
layout "person"
def create
@comment = current_user.comments.new
@comment.article_id = params[:article_id]
@comment.content = params[:comment][:content]
@comment.save!
end
def edit
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
end
def update
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.content = params[:comment][:content]
@comment.save!
end
def useful
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
unless @comment.voted_user.include? current_user.id
@comment.inc(useful_count: 1)
@comment.voted_user << current_user.id
@comment.save
end
end
def useless
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
unless @comment.voted_user.include? current_user.id
@comment.inc(useless_count: 1)
@comment.voted_user << current_user.id
@comment.save
end
end
protected
def permitted_params
params.permit(:comment => [:content, :useful_count, :useless_count])
end
def comment_params
params.permit(:comment => [:content, :useful_count, :useless_count])
end
end
因为在文章中的显示部分
<% if resource.present? %>
<div class="my-growth-article">
<ol class="breadcrumb">
<li><%= link_to "我的成长", articles_path %></li>
<li><%= link_to resource.category, category_index_articles_path(category: resource.category) %></li>
<li class="active"><%= resource.title %></li>
</ol>
<div class="panel panel-default">
<div class="panel-body">
<div class="blk-header custom-bg">
<h3><%= resource.title %></h3>
</div>
<div class="article">
<%= raw resource.content %>
</div>
<hr>
<div class="reply clearfix">
<div class="form-group">
<label for="article-reply">我的评价</label>
<div id="comment_form">
<% comment = resource.comments.find_or_initialize_by(user_id: current_user.id) %>
<% if comment.content.present? %>
<%= render "comments/show", article: resource, comment: comment %>
<% else %>
<%= render "comments/form", article: resource, comment: comment %>
<% end %>
</div>
</div>
</div>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
<div class="blk-header">
<h3>评价</h3>
</div>
<%= render "comments/index" %>
</div>
<% end %>
<%= simple_form_for [article, comment], remote: true do |f| %>
<%= f.input :content, as: :text, label: false, input_html: {class: "form-control", rows: 5, maxlength: "500", placeholder: "留个脚印呗"} %>
<%= f.submit class: "btn btn-lg btn-primary pull-right", id: "comment-submit-btn", value: "发送" %>
<% end %>
<% if @comments.blank? %>
还没有人评价过
<% else %>
<ul class="media-list comments">
<% @comments.all.each do |comment| %>
<li class="media">
<%= image_tag(comment.user.try(:avatar_dynamic_url, :thumb), size: "50x50", class: "pull-left pic")%>
<div class="media-body">
<h5 class="media-heading"><span class="username"><%= comment.user.try(:username) %></span> <span class="date"><%= time_ago_in_words(comment.created_at) %>前</span></h5>
<p><%= comment.content %></p>
<div id="vote_comment_<%= dom_id(comment) %>">
<%= render "comments/vote_comment", article: @article, comment: comment %>
</div>
<a href="#" class="vote-comment text-orange pull-right">回复(<%= comment.child_comments.count %>)</a>
<div class="comments-reply">
<div class="reply clearfix">
<form action="" method="POST" role="form">
<div class="form-group">
<textarea name="article-reply" id="article-reply" cols="30" rows="5" maxlength="500" class="form-control" placeholder="请输入回复内容"></textarea>
</div>
<button type="submit" class="btn btn-lg btn-primary pull-right">发送</button>
</form>
</div>
<!--<ul class="media-list">-->
<!--<% 3.times do %>-->
<!--<li class="media">-->
<!--<span class="pull-left" href="#">-->
<!--<img class="media-object" src="/assets/images/temp_user_avatar.jpg" alt="avatar">-->
<!--</span>-->
<!--<div class="media-body">-->
<!--<h5 class="media-heading"><span class="username">yangguangft</span> <span class="date">5 天前</span></h5>-->
<!--<p>真是个程序猿啊~~~以后自己不会变成这样啊。。。。</p>-->
<!--<p class="vote">-->
<!--<a href="#" class="up"><span class="glyphicon glyphicon-thumbs-up"></span>有用(251)</a>-->
<!--<a href="#" class="down"><span class="glyphicon glyphicon-thumbs-down"></span>没用(12)</a>-->
<!--</p>-->
<!--</div>-->
<!--</li>-->
<!--<% end %>-->
<!--</ul>-->
<a href="#" class="btn btn-bg btn-block btn-lg">查看全部回复...</a>
</div>
</div>
</li>
<% end %>
<li class="media">
<span class="pull-left" href="#">
<img class="media-object" src="/assets/images/temp_user_avatar.jpg" alt="avatar">
</span>
<div class="media-body">
<h5 class="media-heading"><span class="username">zhou307418603</span> <span class="date">11 天前</span></h5>
<p>6分37的时候,我看到impl.js中定义的事getFeoLocation,难道不是getGeoLocation吗?为何最后还是成功了,函数名称就不对啊,初学者表示不理解。6分37的时候,我看到impl.js中定义的事getFeoLocation,难道不是getGeoLocation吗?为何最后还是成功了,函数名称就不对啊,初学者表示不理解。6分37的时候,我看到impl.js中定义的事getFeoLocation,难道不是getGeoLocation吗?为何最后还是成功了,函数名称就不对啊,初学者表示不理解。</p>
<p class="vote">
<a href="#" class="up"><span class="glyphicon glyphicon-thumbs-up"></span>有用(251)</a>
<a href="#" class="down"><span class="glyphicon glyphicon-thumbs-down"></span>没用(12)</a>
<a href="#" class="vote-comment text-orange pull-right">回复(12)</a>
</p>
</div>
</li>
</ul>
<% end %>
<script>
$(function () {
$('.vote-comment').click(function (evt) {
evt.preventDefault();
var $content = $(this).closest('.vote').siblings('.comments-reply');
if($(this).hasClass('active')) {
$content.slideUp('600');
} else {
$content.slideDown('600');
}
$(this).toggleClass('active');
});
});
</script>
<% if @comments.blank? %>
还没有人评价过
<% else %>
<ul class="media-list comments">
<% @comments.all.each do |comment| %>
<li class="media">
<%= image_tag(comment.user.try(:avatar_dynamic_url, :thumb), size: "50x50", class: "pull-left pic")%>
<div class="media-body">
<h5 class="media-heading"><span class="username"><%= comment.user.try(:username) %></span> <span class="date"><%= time_ago_in_words(comment.created_at) %>前</span></h5>
<p><%= comment.content %></p>
<div id="vote_comment_<%= dom_id(comment) %>">
<%= render "comments/vote_comment", article: @article, comment: comment %>
</div>
<a href="#" class="vote-comment text-orange pull-right">回复(<%= comment.child_comments.count %>)</a>
<div class="comments-reply">
<div class="reply clearfix">
<form action="" method="POST" role="form">
<div class="form-group">
<textarea name="article-reply" id="article-reply" cols="30" rows="5" maxlength="500" class="form-control" placeholder="请输入回复内容"></textarea>
</div>
<button type="submit" class="btn btn-lg btn-primary pull-right">发送</button>
</form>
</div>
<!--<ul class="media-list">-->
<!--<% 3.times do %>-->
<!--<li class="media">-->
<!--<span class="pull-left" href="#">-->
<!--<img class="media-object" src="/assets/images/temp_user_avatar.jpg" alt="avatar">-->
<!--</span>-->
<!--<div class="media-body">-->
<!--<h5 class="media-heading"><span class="username">yangguangft</span> <span class="date">5 天前</span></h5>-->
<!--<p>真是个程序猿啊~~~以后自己不会变成这样啊。。。。</p>-->
<!--<p class="vote">-->
<!--<a href="#" class="up"><span class="glyphicon glyphicon-thumbs-up"></span>有用(251)</a>-->
<!--<a href="#" class="down"><span class="glyphicon glyphicon-thumbs-down"></span>没用(12)</a>-->
<!--</p>-->
<!--</div>-->
<!--</li>-->
<!--<% end %>-->
<!--</ul>-->
<a href="#" class="btn btn-bg btn-block btn-lg">查看全部回复...</a>
</div>
</div>
</li>
<% end %>
<li class="media">
<span class="pull-left" href="#">
<img class="media-object" src="/assets/images/temp_user_avatar.jpg" alt="avatar">
</span>
<div class="media-body">
<h5 class="media-heading"><span class="username">zhou307418603</span> <span class="date">11 天前</span></h5>
<p>6分37的时候,我看到impl.js中定义的事getFeoLocation,难道不是getGeoLocation吗?为何最后还是成功了,函数名称就不对啊,初学者表示不理解。6分37的时候,我看到impl.js中定义的事getFeoLocation,难道不是getGeoLocation吗?为何最后还是成功了,函数名称就不对啊,初学者表示不理解。6分37的时候,我看到impl.js中定义的事getFeoLocation,难道不是getGeoLocation吗?为何最后还是成功了,函数名称就不对啊,初学者表示不理解。</p>
<p class="vote">
<a href="#" class="up"><span class="glyphicon glyphicon-thumbs-up"></span>有用(251)</a>
<a href="#" class="down"><span class="glyphicon glyphicon-thumbs-down"></span>没用(12)</a>
<a href="#" class="vote-comment text-orange pull-right">回复(12)</a>
</p>
</div>
</li>
</ul>
<% end %>
<script>
$(function () {
$('.vote-comment').click(function (evt) {
evt.preventDefault();
var $content = $(this).closest('.vote').siblings('.comments-reply');
if($(this).hasClass('active')) {
$content.slideUp('600');
} else {
$content.slideDown('600');
}
$(this).toggleClass('active');
});
});
</script>
<p class="vote">
<%= link_to useful_article_comment_path(article, comment), method: :post, remote: true do %>
<span class="glyphicon glyphicon-thumbs-up"></span>有用(<%= comment.useful_count %>)
<% end %>
<%= link_to useless_article_comment_path(article, comment), method: :post, remote: true do %>
<span class="glyphicon glyphicon-thumbs-down"></span>没用(<%= comment.useless_count %>)
<% end %>
</p>
$("#comment_form").html("");
$("#comment_form").html(<%= raw render("comments/show", article: @article, comment: @comment).inspect %>);
$("#comment_form").html("");
$("#comment_form").html(<%= raw render("comments/form", article: @article, comment: @comment ).inspect %>);
$("#comment_form").html("");
$("#comment_form").html(<%= raw render("comments/show", article: @article, comment: @comment).inspect %>);
$("#vote_comment_<%= dom_id(@comment) %>").html(<%= raw render("comments/vote_comment", article: @article, comment: @comment.reload).inspect %>);