(rails4.1.1, ruby2.1.1)
プロジェクト作成とか
$ rails new favorite_button_sample -T
$ cd favorite_button_sample
ボタン表示を分りやすくするのに CDN の bootstrap 使ってみた
app/views/layouts/application.html.erb
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
ユーザモデル生成
$ rails generate model user name
$ rake db:migrate
class User < ActiveRecord::Base
has_many :comments
has_many :favorites
end
動作確認用ダミー current_user 作成
認証機能つくるの面倒だったので。サンプルだし。
$ rails c
> User.create(name: "foo")
helper_method :current_user
private
def current_user
User.find_or_create_by(id: 1, name: "booboo")
end
コメントのスキャフォールド生成
$ rails generate scaffold comment content:text user:references
$ rake db:migrate
$ rails c
> Comment.create(content: "foo bar baz", user_id: User.first)
class Comment < ActiveRecord::Base
belongs_to :user
has_many :favorites
def favorite_for(user)
favorites.find_by(user_id: user)
end
end
app/views/comments/index.html.erb
<h1>Listing comments</h1>
<table>
<tbody id="comments">
<% @comments.each do |comment| %>
<tr>
<td><%= comment.content %></td>
<td id="comment_<%= comment.id %>">
<%= render 'favorites/favorite_button', comment: comment, favorite: comment.favorite_for(current_user) %>
</td>
<td><%= link_to 'Show', comment %></td>
<td><%= link_to 'Edit', edit_comment_path(comment) %></td>
<td><%= link_to 'Destroy', comment, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Comment', new_comment_path %>
お気に入りモデル生成
rails generate model favorite user:references comment:references
class CreateFavorites < ActiveRecord::Migration
def change
create_table :favorites do |t|
t.references :user, index: true
t.references :comment, index: true
t.timestamps
end
add_index :favorites, [:user_id, :comment_id], unique: true
end
end
resources :favorites, only: [:create, :destroy]
class Favorite < ActiveRecord::Base
belongs_to :user
belongs_to :comment
end
<% if comment.favorite_for current_user %>
<%= link_to "Favorite", favorite_path(favorite), method: :delete, remote: true, class: 'btn btn-xs btn-warning' %>
<% else %>
<%= link_to "Favorite", favorites_path(comment_id: comment), method: :post, remote: true, class: 'btn btn-xs btn-default' %>
<% end %>
$('#comment_<%= @favorite.comment.id %>').html("<%=j render 'favorites/favorite_button', comment: @favorite.comment , favorite: @favorite %>");
$('#comment_<%= @favorite.comment.id %>').html("<%=j render 'favorites/favorite_button', comment: @favorite.comment , favorite: @favorite %>");
class FavoritesController < ApplicationController
def create
@favorite = Favorite.find_or_create_by(comment_id: params[:comment_id], user_id: current_user.id)
render layout: nil
end
def destroy
@favorite = Favorite.find_by(params[:id])
@favorite.destroy
end
end
確認
$ rails s
こんな感じでやった気がする。
もっとスマートなやり方が知りたいっす。
追記
2014-06-19
ツッコミいただいた
宿題出たのでやってみた