1

専攻、キャリア、学校の 3 つのモデルがあります。それぞれにレビューを追加できます。関連付けは次のようになります。

Major.rb、School.rb、Career.rb

has_many :reviews、as :reviewable

レビュー.rb

belongs_to :user
belongs_to :reviewable, polymorphic: true

ユーザー.rb

has_many :レビュー

私のルートは次のようになります。

resources :majors, :schools, :careers do 
  resources :reviews
end

次のような URL にアクセスしたときに、特定のメジャーに関連するすべてのレビューを表示できるようにしたい: majorfinder.com/majors/major-name/reviews しかし、次のエラーが表示されます:

NoMethodError in Reviews#index

Showing /Users/lauraleeflores/Sites/rails/mattan/app/views/reviews/_review.html.erb where line #4 raised:

undefined method `review_path' for #<#<Class:0x007fd788ee3b28>:0x007fd78a9d6930>
Extracted source (around line #4):

1: <% @reviews.each do |review| %>
2:   <tr>
3:     <td><%= review.review %></td>
4:     <td><%= link_to 'Show', polymorphic_path([review.reviewable, review]) %></td>
5: 
6:     <% if current_user == review.user %>
7:      <td><%= link_to 'Edit', edit_major_review_path(review) %></td>

私は今問題を修正しました。同じ問題を抱えている人にとっては、これがどのように解決されたかです:

問題はコントローラーとリンクにありました。

更新されたレビューコントローラーは次のとおりです。

def index
  @reviews = @reviewable.reviews
end

def show
  @review = @reviewable.reviews.find(params[:id])
end

def new
  @review = @reviewable.reviews.build
  @review.user = current_user
end

def edit 
  @review = @reviewable.reviews.find(params[:id])
  raise(ActiveRecord::RecordNotFound, "Access Denied") if @review.user != current_user
end

def create
  @review = @reviewable.reviews.build(params[:review])
  @review.user = current_user
end 

def update
  @review = @reviewable.reviews.find(params[:id])
  raise(ActiveRecord::RecordNotFound, "Access Denied") if @review.user != current_user
end

def destroy
  @review = @reviewable.reviews.find(params[:id])
  @review.destroy
  raise(ActiveRecord::RecordNotFound, "Access Denied") if @review.user != current_user
end

そして、ここに私のレビュー インデックス ページの一部があります。

<% @reviews.each do |review| %>
  <tr>
    <td><%= review.review %></td>
    <td><%= link_to 'Show', major_review_path(@reviewable, review) %></td>

    <% if current_user == review.user %>
        <td><%= link_to 'Edit', edit_major_review_path(@reviewable, review) %></td>
        <td><%= link_to 'Delete', major_review_path(@reviewable, review), method: :delete, data: { confirm: 'Are you sure?' } %></td>
    <% end %>    
  </tr>
<% end %>
<%= link_to 'New Review', new_major_review_path %>

ここに私のショーページの一部があります:

<p>
  <b>Review:</b>
  <%= @review.review %>
</p>

<p>
  <b>Review Profile Name:</b>
  <%= @review.user.profile_name %>
</p>

<p>
  <b>Review User ID:</b>
  <%= @review.user %>
</p>

<p>
  <b>Current User</b>
  <%= current_user %>
</p>

<p>
  <b>Major that this review is for:</b>
  <%= @review.reviewable %>
</p>

<% if current_user == @review.user %>
  <%= link_to 'Edit', edit_major_review_path(@reviewable) %> |
<% end %>
<%= link_to 'Back', major_reviews_path %>

simple_form を使用した新しいレビュー フォームは次のとおりです。

<%= simple_form_for([@reviewable, @review]) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :review %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

私と同じ状況にあった誰かを助けることを願っています!

4

1 に答える 1

1

これは、@reviews コレクションの 1 つ以上のインスタンスにreviewableオブジェクトがないことを意味します。

それがpolymorphic_path([review.reviewable, review])呼び出しを試みる理由ですreview_path(をreview.reviewable返すためnil

アップデート:

コントローラーのレビュー:

before_filter :reviewable

def reviewable
  @reviewable = if params[:major_id]
    Major.find(params[:major_id])
  elsif params[:school_id]
    School.find(params[:school_id])
  elsif params[:career_id]
    Career.find(params[:career_id])
  end
end

def index
  @reviews = @reviewable.reviews
end

def show
  @review = @reviewable.reviews.find(params[:id])
end

def new
  @review = @reviewable.reviews.build
  @review.user = current_user
  # @review = current_user.reviews.new
  # @review.reviewable = @reviewable
end

def create
  @review = @reviewable.reviews.build(params[:review])
  @review.user = current_user
  # @review = current_user.reviews.new(params[:review])
  # @review.reviewable = @reviewable
  ... save etc
end 

def edit 
  @review = @reviewable.reviews.find(params[:id])
  raise(ActiveRecord::RecordNotFound, "Access Denied") if @review.user != current_user
end

def update
  @review = @reviewable.reviews.find(params[:id])
  raise(ActiveRecord::RecordNotFound, "Access Denied") if @review.user != current_user
end

アプリ/ビュー/レビュー/_form.html.erb:

<%= simple_form_for([@reviewable, @review]) do |f| %> # or <%= simple_form_for([@review.reviewable, @review]) do |f| %>
...

次に、ページを取得してみてください。

majorfinder.com/majors/major-name/reviews

majorfinder.com/majors/major-name/reviews/new

majorfinder.com/majors/major-name/reviews/review_id/edit

それはあなたが探していたものでしたか?:)

于 2013-03-16T23:03:49.947 に答える