Reputation: 3800
I have a nested reviews model with a polymorphic association with majors, careers, and schools. I want users to review these majors, schools, and careers on their show page. In addition, I want them to see all the reviews they've made on their profile page.
I can get the reviews to show but I am having trouble with adding, editing, and deleting them because I want them to be able to do these actions when they see their review on the major, school, career, or their profile page.
Here are my routes:
resources :majors, :schools, :careers do
resources :reviews
end
Here are my associations:
Major.rb, School.rb, Career.rb
has_many :reviews, as :reviewable
Review.rb
belongs_to :user
belongs_to :reviewable, polymorphic: true
User.rb
has_many :reviews
Here is my reviews_controller.rb:
before_filter :reviewable
def index
@reviews = @reviewable.reviews
@major = Major.includes(:reviews => :user).find_by_slug(params[:id])
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
@reviews = @reviewable.reviews
end
def destroy
@review = @reviewable.reviews.find(params[:id])
@review.destroy
raise(ActiveRecord::RecordNotFound, "Access Denied") if @review.user != current_user
end
def reviewable
@reviewable = if params[:major_id]
Major.find_by_slug!(params[:major_id])
elsif params[:school_id]
School.find(params[:school_id])
elsif params[:career_id]
Career.find(params[:career_id])
end
end
In order to create, view, and edit a review for a major, for instance, they will be doing it on the major show page. This is what I have on majors_controller.rb:
def show
@reviews = Review.includes(:user)
@reviews_most_liked = Review.order("created_at DESC").limit(4)
end
I'm trying to make it so they can add and edit from a modal window inside the major, school, and career show page. Here's what I have in the modal window:
<%= 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 %>
Upvotes: 3
Views: 2307
Reputation: 3800
I figured it out. The problem was with mapping the right instance variables with the correct action and controller. Most of instance variables were placed in my majors_controller.rb, school_controller.rb, and careers_controller.rb show action. This is what part of my majors_controller.rb show action - I was mistakenly placing them in the create action and delete action. But, once I sat and thought about it I realized it's all happening within the show page. Here's what my controller for my models look like:
def show
@reviewable = @major
@reviews = @reviewable.reviews #show reviews
@reviews_most_liked = @reviewable.reviews.order("created_at DESC").limit(2)
@reviews_most_liked_2 = @reviewable.reviews.order("created_at DESC").limit(2).offset(2)
@review = @reviewable.reviews.build(params[:review]) #create a review
@review.user = current_user #connect the created review to the user
end
Then in my majors show.html.erb page I was able to call the show method by calling the person who gave the review:
<%= review.user.profile_name %>
and the review itself:
<%= review.review %>
That displays the review. I then needed to create, edit and delete. In order to create I just had to get the instance variables correct. Once I got them correct in the right controller and under the correct action (majors controller show action) then in the modal window on the majors show page I called the form partial:
<%= render 'reviews/form' %>
which looks like this:
<%= simple_form_for([@reviewable, @review]) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :review, :input_html => { :class => "span4", :rows => 10 },
label: false,
placeholder: 'Help others by sharing what you\'ve learned as a major.' %>
</div>
<div class="modal-footer">
<button class="btn cancel-modal-review" data-dismiss="modal" aria-hidden="true">Cancel</button>
<%= f.submit 'Share My Review', :class => "submit-feedback" %>
</div>
<% end %>
Upvotes: 2