12步給商品增加收藏功能

Published on:

collection products

1.migration
$ rails g migration add_user_id_to_product user_id:integer
$ rake db:migrate

2.model
$ rails g model product_relationship user_id:integer product_id:integer
$ rake db:migrate

3.connection

user.rb
has_many :product_relationships
  has_many :collected_products, through: :product_relationships, source: :product
product.rb
has_many :product_relationships
  has_many :members, through: :product_relationships, source: :user
product_relationship.rb
belongs_to :user
belongs_to :product

4.has_collected?

user.rb
def has_collected?(product)
  collected_products.include?(product)
end

5.controller
$ rails g controller account::collections

app/controllers/account/collections_controller.rb
class Account::CollectionsController < ApplicationController
  before_action :authenticate_user!
  
  def index
    @products = current_user.collected_products
  end
end

6.view

app/views/account/collections/index.html.erb
<% @products.each do |product|%>
  <p><%= link_to(product.title, product_path(product)) %></p>
  <p><%= product.description %></p>
  <p><%= product.price %></p>
<% end %>

7.routes

routes.rb
namespace :account do
  resources :collections
end

8.collect & discollect

user.rb
def collect!(product)
    collected_products << product
  end

  def discollect!(product)
    collected_products.delete(product)
  end

9.add method to products_controller

products_controller.rb
def collect
    @product = Product.find(params[:id])

    if !current_user.has_collected?(@product)
      current_user.collect!(@product)
      flash[:notice] = "You've successfully collected the skill!"
    else
      flash[:warning] = "You've already collected the skill!"
    end

    redirect_to product_path(@product)
  end

  def discollect
    @product = Product.find(params[:id])

    if current_user.has_collected?(@product)
      current_user.discollect!(@product)
      flash[:alert] = "You've successfully discollected the skill!"
    else
      flash[:warning] = "You haven't collected the skill yet!"
    end

    redirect_to product_path(@product)
  end

10.add to routes

routes.rb
resources :products do
    member do
      post :collect
      post :discollect
    end

11.add button

products/show.html.erb
<div class="pull-right">
    <% if current_user && current_user.has_collected?(@product) %>
      <%= link_to("取消收藏", discollect_product_path(@product), method: :post, class: "btn btn-default")  %>
    <% else %>
      <%= link_to("收藏", collect_product_path(@product), method: :post, class: "btn btn-default")  %>
    <% end %>
  </div>

12.dropdown on navbar

_navbar.html.erb
<ul class="dropdown-menu">
                       <% if current_user.admin? %>
                          <li>
                            <%= link_to(content_tag(:i, "管理员后台", class: "fa fa-user-circle-o"), admin_products_path ) %>
                          </li>
                          
                        <% end %>
                        <li>
                           <%= link_to(content_tag(:i, "我的订单", class: "fa fa-chevron-circle-down"), account_orders_path )%>
                        </li>
+                        <li>
+                           <%= link_to(content_tag(:i, "我的收藏", class: "fa fa-star"), account_collections_path )%>
+                        </li>
                       <li>
                          <%= link_to(content_tag(:i, "登出", class: "fa fa-sign-out"), destroy_user_session_path, method: :delete)%>
                       </li>
                   </ul>

Comments

comments powered by Disqus