1

私はこれを解決しました。詳細については、私が投稿した回答を参照してください。基本的に、フォーム内にフォームがあり、両方に 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_idfollowed_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 を愛用していますが、この問題はループに陥っています。

4

2 に答える 2