为什么在实现"favorites"时提交错误的操作,模仿迈克尔·哈特尔在 Rails 教程中的追随者/追随者



我解决了这个问题。有关详细信息,请参阅我发布的答案。基本上,我有一个表单中的表单,两者都有一个 POST 操作。我消除了外部形式。

更新3:这几乎可以工作,但是现在我的收藏夹控制器创建方法给出了一个奇怪的错误:

错误的参数类型模块(预期的类(

这是"添加到收藏夹"按钮部分:

<%= form_for(current_user.favorites.build(followed_event_id: user_event.id)) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites", class: "info_inline_control info_button_small user_event_summary_item" %>
<% end %>

以下是收藏夹控制器创建操作:

def create
  @user_event = UserEvent.find(params[:favorite][:followed_event_id])
  current_user.follow!(@user_event)
end

这是用户模型遵循!(( 方法

def follow!(user_event)
  favorites.create!(followed_event_id: user_event.id)
end

更新 2:当我查看源代码时,包含"添加到收藏夹"按钮的表单包含在搜索结果项的表单中。因此,用户搜索事件,获取搜索结果,并且每个项目都呈现为一个表单,其中包含"添加到收藏夹"按钮的另一个表单。

但是这种外部形式有一个方法="post",这似乎是问题所在。

创建该外部表单是因为我使用的是form_for,所以我删除了它,现在没有外部形式。但是,当呈现"添加到收藏夹"按钮部分时,将保存收藏夹,而不是在单击按钮时保存。这就是我现在需要解决的问题。这么近...


更新

:我终于能够添加收藏夹了,但不幸的是,当单击"添加到收藏夹"按钮时,除了保存收藏夹记录外,还调用了用户事件更新操作。当用户取消关注事件时,这一点最为重要,因为这会删除该事件,而不是他们的事件。

以下是收藏夹控制器中的收藏夹创建方法:

def create
  @user_event = UserEvent.find(params[:favorite][:followed_event_id])
  current_user.follow!(@user_event)
end

下面是用户模型中的 follow(( 方法:

def follow!(user_event)
  favorites.create!(followed_event_id: user_event.id)
end

这是带有"添加到收藏夹"按钮的部分:

<%= form_for(current_user.favorites.create!(followed_event_id: user_event.id)) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites" %>
<% end %>

隐藏字段会不会有问题?

当创建"收藏夹"关系时,在抽象意义上,用户事件正在更新(因为它现在通过收藏夹与用户关联(,但我认为它不会触发用户事件的更新。


我希望我在这里分享的信息足以帮助您帮助我。

我有一个活动策划应用程序,用户可以创建活动。用户还可以搜索事件并单击按钮将事件添加到他们的"收藏夹"。

我以Michael Hartl的Rails Tutorial为模型,在该教程中,他允许用户关注(因此被其他用户关注(。

我对他的范式的使用不同,因为用户"关注"事件,而不是关注其他用户。从这个意义上说,一个用户被事件"关注",因为如果十个用户关注一个特定事件,事件就是在关注这些用户。我希望我有正确的抽象部分。

我的问题是当用户单击"关注"按钮时,不会在"收藏夹"表中创建一行(带有following_user_idfollowed_event_id(。相反,有点神秘地调用了events_controller更新操作。

我应该提到"添加到收藏夹"按钮出现在搜索结果"显示"页面上,它使每个搜索结果项的_user_event.html.erb部分。

因此,用户在搜索结果"显示"页面上,带有"添加到收藏夹"按钮,此按钮是添加收藏夹表单的一部分,该表单在提交时正在提交以更新事件,这是错误的。

下面是一些代码,希望能帮助您了解我的方案。顺便说一句,我在这里真的有两个问题,为什么提交添加到收藏夹表单以更新事件,以及我是否通过范式正确实现了此has_many。提前非常感谢。

-------------- user.rb MODEL --------------------
...
  has_many :user_events, dependent: :destroy
  has_many :favorites, foreign_key: "followed_event_id", dependent: :destroy
  has_many :followed_events, through: :favorites, source: :followed_event
...
  def following?(user_event)
    favorites.find_by_followed_event_id(user_event.id)
  end
  def follow(user_event)
    favorites.create!(followed_event_id: user_event.id)
  end
  def unfollow(user_event)
    favorites.find_by_followed_event_id(user_event.id).destroy    
  end
---------------- user_event.rb MODEL -------------------
...
  belongs_to :user
  has_many :favorites
  has_many :favorited_by, through: :favorites, source: :user
...
------------------------ favorite.rb MODEL --------------------
class Favorite < ActiveRecord::Base
  attr_accessible :followed_event_id
  belongs_to :following_user, class_name: "User"
  belongs_to :followed_event, class_name: "UserEvent"
  has_many :reverse_favorites, foreign_key: "followed_event_id",
                               class_name: "Favorite",
                               dependent: :destroy
  has_many :following_users, through: :reverse_favorites, 
                             source: :following_user                               
  validates :following_user_id, presence: true
  validates :followed_event_id, presence: true
end
----------------- config/routes.rb -----------------------
...
  resources                 :users do
    member do
      get :following_users, :followed_events 
    end
  end
...
  resources                 :user_events
  resources                 :favorites, only: [:create, :destroy]
...

---------------- favorites_controller.rb --------------
class FavoritesController < ApplicationController
  before_filter :signed_in_user
  def create
    @user_event = UserEvent.find(params[:favorite][:user_event])
    current_user.follow!(@user_event)
    redirect_to @user
  end
  def destroy
    @user_event = Favorite.find(params[:id]).followed_event
    current_user.unfollow!(@user_event)
    redirect_to @user
  end
end
----------------- migration --------------------
class CreateFavorites < ActiveRecord::Migration
  def change
    create_table :favorites do |t|
      t.integer :following_user_id
      t.integer :followed_event_id
      t.timestamps
    end
  end
end
----------------- search "show" view -----------------
<h2>Search Results</h2>    
<%= render @search.user_events %>
------------- _user_event.html.erb -------------
...
<% if (signed_in? && current_user && current_user.id != user_event.user_id) %>
  <%= render partial: "shared/add_remove_favorite", locals: { user_event: user_event } %>
<% end %>
<%= user_event.title %></span>
...
--------------- _add_remove_favorite.html.erb ------------
<% if current_user.following?(user_event) %>
  <%= render partial: 'shared/remove_favorite', locals: { user_event: user_event } %>
<% else %>
  <%= render partial: 'shared/add_favorite', locals: { user_event: user_event } %>
<% end %>
-------------- _add_favorite.html.erb ---------------------
<%= form_for(current_user.favorites.build(followed_event_id: user_event.id)) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites" %>
<% end %>
--------------------- _remove_favorite.html.erb ---------------
<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
    html: { method: :delete }) do |f| %>
  <%= f.submit "Remove from favorites" %>
<% end %>

很多代码,我希望你能理解我的问题并提供帮助。我的应用程序已经完成了大约 70%,到目前为止我一直很喜欢 Rails,但这个问题让我陷入了循环。

解决了最后一个问题。我的收藏夹控制器继承自ActionController,这是一个错字,它应该是ApplicationController。这不是核心问题。核心问题是我在表单中有一个表单,而在生成的 HTML 中,两个表单都有一个 post 操作。因此,当单击"添加到收藏夹"按钮时,已提交外部表单。解决方案是将div 从外部形式中取出。

这是我现在工作的基本代码 保存到收藏夹 实现。只有我认为相关的代码。完整的代码太大。

感谢您的帮助!

------------迁移以创建收藏夹表------------------

class CreateFavorites < ActiveRecord::Migration
  def change
    create_table :favorites do |t|
      t.integer :following_user_id
      t.integer :followed_event_id
      t.timestamps
    end
  end
end

---------------增加了路线-----------------------

resources                 :users do
  member do
    get :following_users, :followed_events
  end
end
resources                 :favorites, only: [:create, :destroy]

---------------- 最喜欢的型号-----------------

class Favorite < ActiveRecord::Base
  attr_accessible :followed_event_id
  belongs_to :following_user, class_name: "User"
  belongs_to :followed_event, class_name: "UserEvent"
  validates  :following_user_id, presence: true 
  validates  :followed_event_id, presence: true 
end

------------------ 用户模型----------------------

has_many :user_events, dependent: :destroy
has_many :favorites, foreign_key: :following_user_id, dependent: :destroy 
has_many :followed_events, through: :favorites, source: :followed_event
def following?(user_event)
  favorites.find_by_followed_event_id(user_event.id)
end
def follow!(user_event)
  favorites.create!(followed_event_id: user_event.id)
end
def unfollow!(user_event)
  favorites.find_by_followed_event_id(user_event.id).destroy
end

--------------------用户事件模型----------------------

belongs_to :user
has_many :favorites, foreign_key: :followed_event_id, dependent: :destroy 
has_many :following_users, through: :favorites, source: :following_user

--------------收藏夹控制器-------------------------

class FavoritesController < ApplicationController
  before_filter :signed_in_user
  def create
    @user_event = UserEvent.find(params[:favorite][:followed_event_id])
    current_user.follow!(@user_event)
    redirect_to user_path(current_user)
  end
  def destroy
    @user_event = Favorite.find(params[:id]).followed_event
    current_user.unfollow!(@user_event)
    redirect_to user_path(current_user)
  end
end

----------------用户控制器----------------------------

def following_users
  @user_event = UserEvent.find(params[:id])
  @users = @user_event.following_users
end
 def followed_events
  @user = User.find(params[:id])
  @user_events = @user.followed_events
 end

------------ _add_remove_favorite.html.erb ----------------

<% if current_user.following?(user_event) %>
  <%= render partial: 'shared/remove_favorite', locals: { user_event: user_event } %>
<% else %>
  <%= render partial: 'shared/add_favorite', locals: { user_event: user_event } %>
<% end %>

------------- _add_favorite.html.erb ------------------------

<%= form_for(current_user.favorites.build(followed_event_id: user_event.id)) do |f| %>
  <div class="hidden"><%= f.hidden_field :followed_event_id %></div>
  <%= f.submit "Add to favorites", class: "info_inline_control info_button_small user_event_summary_item" %>
<% end %>

------------- _remove_favorite.html.erb ----------------------

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
             html: { method: :delete }) do |f| %>
  <%= f.submit "Remove from favorites", class: "info_inline_control info_button_small user_event_summary_item" %>
<% end %>

-------------- 显示收藏夹的用户显示页面代码显示.html.erb ------------------

<h3 class="purple_text top_margin_thirty">Your Favorites</h3>
<div>
  <% if @user.followed_events.any? %>
    <h4 class="green_text info_inline_control">Your favorites include <%= pluralize(current_user.followed_events.count, "event") %> !</h4>
    <div class="favorites">
      <%= render @user.followed_events %>
    </div>
  <% else %>
    <h4 class="green_text no_events">You have no favorite events</h4>
    <%= link_to "Find an Event", new_search_path, class: "post_find_event_link" %>
  <% end %>
</div>

用户模型中有错误。它应该是:

class User < ActiveRecord::Base
  has_many :user_events, dependent: :destroy
  has_many :favorites, foreign_key: :following_user_id, dependent: :destroy
  has_many :followed_events, through: :favorites, source: :followed_event
  # ...
end

试试这个,看看会发生什么。我不确定这是否可以解决您的错误。

最新更新