私はこれを解決しました。詳細については、私が投稿した回答を参照してください。基本的に、フォーム内にフォームがあり、両方に POST アクションがあります。外形をなくしました。
更新 3: これはほとんど機能していますが、私の FavoritesController create メソッドで奇妙なエラーが発生しています:
間違った引数の型のモジュール (期待されるクラス)
「お気に入りに追加」ボタンの一部を次に示します。
<%= 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
そして、ここに User モデルの follow!() メソッドがあります
def follow!(user_event)
favorites.create!(followed_event_id: user_event.id)
end
更新 2: ソースを表示すると、[お気に入りに追加] ボタンを含むフォームが検索結果アイテムのフォーム内に含まれています。したがって、ユーザーはイベントを検索し、検索結果を取得し、各アイテムは [お気に入りに追加] ボタン用の別のフォームを含むフォームとしてレンダリングされます。
しかし、その外側のフォームには method="post" があり、それが問題のようです。
その外側のフォームは、form_for を使用していたために作成されたので、それを削除したところ、外側のフォームはありません。ただし、ボタンがクリックされたときではなく、[お気に入りに追加] ボタンのパーシャルがレンダリングされたときにお気に入りが保存されます。それが私が今解決しなければならないことです。とても近い...
更新: ようやくお気に入りを追加できるようになりましたが、残念ながら [お気に入りに追加] ボタンをクリックすると、お気に入りのレコードが保存されるだけでなく、ユーザー イベントの更新アクションが呼び出されます。これは、ユーザーがイベントのフォローを解除したときに最も重要です。これは、そのイベントが削除され、そのイベントではないためです。
FavoritesController の favorites create メソッドは次のとおりです。
def create
@user_event = UserEvent.find(params[:favorite][:followed_event_id])
current_user.follow!(@user_event)
end
User モデルの 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 チュートリアルに倣ってモデル化しました。このチュートリアルでは、ユーザーが他のユーザーをフォローできる (したがってフォローされる) ことができます。
ユーザーが他のユーザーをフォローするのではなく、イベントを「フォロー」するため、彼のパラダイムの私の使い方は異なります。この意味で、10 人のユーザーが特定のイベントをフォローしている場合、イベントはそれらのユーザーをフォローしていることになるため、ユーザーはイベントによって "フォローされている" と言えます。抽象化のその部分が正しいことを願っています。
私の問題は、ユーザーが「フォロー」ボタンをクリックすると、「お気に入り」テーブルの行が作成されないことです(following_user_id
とfollowed_event_id
)。代わりに、やや不思議なことに、events_controller
更新アクションが呼び出されます。
検索結果の「表示」ページに「お気に入りに追加」ボタンが表示され、_user_event.html.erb
各検索結果項目の部分が表示されます。
したがって、ユーザーは検索結果の「表示」ページに「お気に入りに追加」ボタンがあり、このボタンはお気に入り追加フォームの一部であり、送信時にイベントを更新するために送信されますが、これは間違っています。
これが私のシナリオを理解するのに役立つことを願っています。ところで、ここで本当に 2 つの質問があります。お気に入りに追加フォームを送信してイベントを更新するのはなぜですか。パラダイムを介してこの 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 を愛用していますが、この問題はループに陥っています。