喜欢/不喜欢没有Ajax或jQuery on Rails

我正在尝试实现一个简单的喜欢/不同的function。 我在这里看到的所有例子似乎都适用于ajax或jquery。 我还是初学者,我还没有完全理解,我只想要一个简单的解决方案。

我的想法是,我有书,我有用户。 用户可以喜欢书籍。 所以我通过Like模型创建了一个多对多的关联。 Like模型具有相应的数据库,其中包含book_id和user_id列。 从而:

class Book < ActiveRecord::Base has_many :likes has_many :users, through: :likes class User < ActiveRecord::Base has_many :likes has_many :books, through: :likes class Like < ActiveRecord::Base belongs_to :book belongs_to :user end 

不幸的是,这是我的理解。 我不知道如何利用这种关系来创建喜欢并将它们与相应的书籍和用户相关联。

我的想法是,如果用户不喜欢这本书,则向用户展示“喜欢”按钮,或者如果他没有喜欢,则为用户提供“喜欢”按钮。 所以基本上,我想要这么简单:

  

我使用了#stub,因为我不知道它应该使用什么路由。 但无论解决方案是什么,我都希望它重定向到相同的页面,闪存通知说“喜欢”或“不喜欢”。 我已经为like_button和different_button类提供了div背景图像,这就是我将它们作为上面的图像链接实现的原因。

任何forms的指导或帮助,将深表感谢。 谢谢

UPDATE

我在下面跟随Bennick的指导,但我仍然坚持使用rails控制台。 我认为如果我在控制台中出现错误,那么前进是没有意义的。

如建议的那样,我在控制台中尝试了这个:

由于我已经有用户,我做了user = User.find(1)book = Book.find(1)

但是在下一行like = Like.create(:user => user, :book => book) ,返回了一个质量分配错误。 Can't mass-assign protected attributes: book, user我认为这可能有助于attr_accessible :book_id, :user_id在类似的模型中,但我仍然会得到错误。 我错过了什么吗?

解决了

我终于开始工作了! 使用like = Like.create(:user => user.id, :book => book.id)

好的,这里有很多项目。 我要把你带到堆栈模型 – > 关联 – > 控制器 – > 视图 – > 路由器 )。 通常,在设计Web应用程序时,您需要从数据库层开始,然后逐步完成工作。 所以我们会在这里做。

模型

您可以在此处决定所需的数据库对象,并创建数据库表来表示它们。 如果您还没有,请阅读Rails Rails指南: 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中,此安全function已移至控制器中。 有关这方面的更多信息,请参阅这些内容或搜索内部网: http : //blog.teamtreehouse.com/rails-4-strong-paremeters http://weblog.rubyonrails.org/2012/3/21/strong-parameters/

协会

您应该阅读关于协会的Rails指南: 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 => # # Create two a books book = Book.create(:title => "Game of Thrones") => # book2 = Book.create(:title => "The Well-Grounded Rubyist") => # # Create a two likes from the books and the user record like = Like.create(:user => user, :book => book) => # like2 = Like.create(:user => user, :book => book2) => # # Notice how the keys glue the associations # Query a user's likes user.likes.count => 2 user.likes => #, #] # Query a user's books user.books => #, #] 

如果有疑问,请使用rails控制台。 你将从中学到很多东西。

调节器

为了使最终用户与您的数据库对象进行交互,需要一个控制器来促进交换。 再次,阅读相关的Rails指南: 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 

路由器

路由器将外部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它将解释这些路由是什么以及它们如何工作。 Rails遵循REST,就像大多数现代Web开发世界一样。

视图

在您的视图中,您将需要一个表单供用户进行交互。 此表单将数据发送到应用程序,特别是LikesController操作。

 # app/views/likes/index.html.erb # show your flash messages <% flash.each do |name, msg| %> 
"> <%= msg %>
<% end %>

Books you may or may not like

# 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
# Clicking this sends a request to: DELETE /likes/123 <%= link_to "destroy like", likes_path(like.id), :method => :delete %>
<% end %> <% end %>

结论

我希望这会给你一些指导。

在将来尝试并使您的问题更具体,因为这个问题涵盖了一个很大的领域。 我刚刚开始积极回馈所以我可能已经完成了它。 我在第一次出发时收到了大量的免费指导和帮助。 现在是时候我回报了。

花点时间,当您收到错误时,只需将其发布到Google。 您最终可能会遇到Stack Overflow问题。

干杯!