好的,这里有很多项目。我将带你上去stack (model -> 协会 -> 控制器 -> view -> router)。通常,当您设计 Web 应用程序时,您会从数据库层开始,然后逐步向上。所以我们将在这里这样做。
Model
您可以在此处决定需要哪些数据库对象并创建数据库表来表示它们。如果您还没有阅读 Rails 迁移指南:http://guides.rubyonrails.org/migrations.html http://guides.rubyonrails.org/migrations.html
对于您的情况,此设置是合适的:
class Book < ActiveRecord::Base
attr_accessible :title
has_many :likes
has_many :users, through: :likes
end
class User < ActiveRecord::Base
attr_accessible :name
has_many :likes
has_many :books, through: :likes
end
class Like < ActiveRecord::Base
attr_accessible :book, :user
belongs_to :book
belongs_to :user
end
请注意,我们需要包括attr_accessible
所以我们不会出现任何质量分配错误。请注意,在 Rails 4 中,此安全功能已移至控制器中。有关这方面的更多信息,请参阅这些或搜索互联网:http://blog.teamtreehouse.com/rails-4-strong-paremeters http://blog.teamtreehouse.com/rails-4-strong-paremeters
http://weblog.rubyonrails.org/2012/3/21/strong-parameters/ http://weblog.rubyonrails.org/2012/3/21/strong-parameters/
协会
您应该阅读有关关联的 Rails 指南:http://guides.rubyonrails.org/association_basics.html http://guides.rubyonrails.org/association_basics.html
这将使您很好地了解数据库对象(Active Record 对象)如何相互交互。在你的问题中你已经设置了这些。一旦建立关联,Rails 就会提供许多用于访问它们的方法。下面是一个 Rails 控制台会话示例:rails c
# Create a user
user = User.create(:name => "Ryan") # I'm assuming User just requires a name for simplicity
=> #<User id: 1, name: "Ryan">
# Create two a books
book = Book.create(:title => "Game of Thrones")
=> #<Book id: 1, title: "Game of Thrones">
book2 = Book.create(:title => "The Well-Grounded Rubyist")
=> #<Book id: 2, title: "The Well-Grounded Rubyist">
# Create a two likes from the books and the user record
like = Like.create(:user => user, :book => book)
=> #<Like id: 1, user_id: 1, book_id: 1>
like2 = Like.create(:user => user, :book => book2)
=> #<Like id: 2, user_id: 1, book_id: 2>
# Notice how the keys glue the associations
# Query a user's likes
user.likes.count
=> 2
user.likes
=> #<ActiveRecord::Associations::CollectionProxy [#<Like id: 1, user_id: 1, book_id: 1>, #<Like id: 2, user_id: 1, book_id: 2>]
# Query a user's books
user.books
=> #<ActiveRecord::Associations::CollectionProxy [#<Book id: 1, title: "Game of Thrones">, #<Book id: 1, title: "The Well-Grounded Rubyist">]
如有疑问,请使用 Rails 控制台。你会从中学到很多东西。
控制器
为了使最终用户与数据库对象进行交互,需要控制器来促进交换。再次阅读相关的 Rails 指南:http://guides.rubyonrails.org/action_controller_overview.html http://guides.rubyonrails.org/action_controller_overview.html如果您现在还没有猜到,我强烈建议您阅读其中的大部分内容。
为了您的原因,我们正在创建类似的对象,因此让我们创建一个类似的控制器:
rails g controller likes index
这将创建带有索引操作和视图文件的控制器。
# app/controllers/likes_controller.rb
class LikesController < ApplicationController
# This action will show our likes for a user.
# Lets assume you have an authentication system (ex Devise) that logs a user in and provides a `current_user` object
# GET /likes
def index
# Assign the logged in user to @user
@user = current_user
# Grab all of the books and put them into an array in @books
@books = Book.all
end
# This is our key action. We will use this action to create a Like
# POST /likes
def create
# Grab our book from the DB. Note that this syntax is for Rails 3.2 and below. Rails 4 uses something called Strong Parameters, but that is for another time.
book = Book.find(params[:book_id])
# Create a like
Like.create(:book => book, :user => current_user)
# redirect back to the Like index page and assign a flash
redirect_to likes_path, :notice => "You just liked the book #{book.title}"
end
# here is where we will destroy a Like
# DELETE /likes/:id
def destroy
# Get the like form the DB
like = Like.find(params[:id])
# destroy it
like.destroy
redirect_to likes_path, :notice => "You destroyed a like"
end
end
Router
路由器将外部 http 请求连接到控制器操作。就您而言,您所需要的只是:
# config/routers.rb
MyApp::Application.routes.draw do
resources :likes
end
这是一个 Rails 快捷方式,它设置了 7 条标准路由以及相关的帮助程序:
likes GET /likes(.:format) likes#index
POST /likes(.:format) likes#create
new_like GET /likes/new(.:format) likes#new
edit_like GET /likes/:id/edit(.:format) likes#edit
like GET /likes/:id(.:format) likes#show
PUT /likes/:id(.:format) likes#update
DELETE /likes/:id(.:format) likes#destroy
帮自己一个忙,阅读本指南:http://guides.rubyonrails.org/routing.html http://guides.rubyonrails.org/routing.html它将解释这些路线是什么以及它们如何工作。 Rails 遵循 REST,就像大多数现代 Web 开发世界一样。
View
在您看来,您将需要一个供用户交互的表单。此表单会将数据发送到应用程序,特别是您的 LikesController 操作。
# app/views/likes/index.html.erb
# show your flash messages
<% flash.each do |name, msg| %>
<div class="alert <%= "alert-#{name}" %>">
<%= msg %>
</div>
<% end %>
<h1>Books you may or may not like</h1>
# For each book
<% @books.each do |book| %>
<% unless @user.books.include?(book) %> # Prob want to move this into a User instance method
# Create a like form if the user does not have a like for this book
<%= form_tag likes_path do %>
<%= hidden_field_tag 'book_id', book.id %>
# Clicking this sends a request: POST /likes with params of: book_id=123
<%= submit_tag "Like this book", :class => "like_button" %>
<% end %>
<% else %>
# Find the like. I'll admit there is probably a better way to do this but it's getting past my bed time.
<% like = book.likes.where(:user_id => @user.id).first %>
# Destroy the like associated with this book and user
<div class="unlike_button">
# Clicking this sends a request to: DELETE /likes/123
<%= link_to "destroy like", likes_path(like.id), :method => :delete %>
</div>
<% end %>
<% end %>
结论
我希望这能给您一些指导。
将来尝试让您的问题更加具体,因为这个问题涵盖了很大的领域。我刚刚开始积极回馈社会,所以我可能做得有些过头了。刚开始时我收到了大量免费的指导和帮助。是时候回报我的恩情了。
慢慢来,当您遇到错误时,只需将其发布到 Google 即可。您可能最终会遇到 Stack Overflow 问题。
Cheers!