Good afternoon people
I am trying to create a tobacco viewing application, for nothing but to learn more. I tried to use what Ive learned in the Rails Tutorial, however, I always run into brick walls and grills that I donβt understand. I can normally overcome the undefined `something 'method for nil: NilClass and the other problems that I have, but it really causes me a dead end because Ive got my tests.
My tests
review_test.rb
require 'test_helper' class ReviewTest < ActiveSupport::TestCase
user_test.rb
Fixtures
reviews.yml
one: rating: 5 tobacco_id: 1 comment: "This is a super snus" created_at: <%= 3.hours.ago %> two: rating: 5 tobacco_id: 1 comment: "This is the best snus in the world" created_at: <%= 2.hours.ago %> three: rating: 5 tobacco_id: 1 comment: "I will always buy this snus" created_at: <%= 1.hours.ago %> most_recent: rating: 5 tobacco_id: 1 comment: "I have a shed load of this snus, it great!" created_at: <%= Time.zone.now %>
Models
review.rb
belongs_to :tobacco
tobacco.rb
has_many :reviews
user.rb
has_many :tobaccos, dependent: :destroy has_many :reviews, dependent: :destroy
reviews_controller.rb controller
def new @review = Review.new end
This is what I have for the create action in the controller, but I canβt say if I have it right, because I canβt load the page yet. Any suggestions for creating an action would be very helpful if I asked another question, if I have it wrong, which I probably have!
def create @tobacco = Tobacco.find(params[:tobacco_id]) @review = @tobacco.reviews.new(params[:review].permit(:tobacco_id, :comment)) @review.user = User.find(current_user.id) @review.save redirect_to tobacco_path(@tobacco) end
Routes
resources :tobaccos do resources :reviews, except: [:show, :index] end
show.html.erb
<%= link_to "Write a Review", new_tobacco_review_path(@tobacco) %>
new.html.erb
<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %> <%= render 'fields', f: f %> <%= f.submit "Save Review", class: 'btn btn-primary' %> <% end %>
When I go to the page to write a review, I get an error
Showing C:/Sites/apps/review/app/views/reviews/new.html.erb where line #11 raised: undefined method `reviews' for nil:NilClass
That tells me it's line 11
<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %>
but all that I try, I get another error. I know this is a rookie mistake, but I don't see it.
Thank you in advance
Sean
UPDATE
I have work and save in the database now, I did it like this In the reviews_controller.rb new and created look like this:
def new @tobacco = Tobacco.find(params[:tobacco_id]) end def create @tobacco = Tobacco.find(params[:tobacco_id]) @review = Review.new(review_params) @review.user_id = current_user.id @review.tobacco_id = @tobacco.id if @review.save redirect_to @tobacco else render 'new' end end
Param Overview
def review_params params.require(:review).permit(:rating, :comment, :tobacco_id) end
Everything looks right for me, and it works, so I hope everything will be fine.
Now I'm stuck in editing a tobacco review. This is the first time I have worked on nested routes. I just looked at a couple of tutorials, but nothing helped me fix it. I'm not sure how to pass these keys ...
On the show page I have this
<%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %>
The show tobaccos_controller.rb method looks like this:
def show @tobacco = Tobacco.find(params[:id]) @reviews = Review.where(tobacco_id: @tobacco.id) end
In reviews_controller.rb I have this
def edit @tobacco = Tobacco.find(params[:tobacco_id]) @review = Review.find(params[:id]) end
And the error I get is
ActionController::UrlGenerationError in Tobaccos#show No route matches {:action=>"edit", :controller=>"reviews", :id=>nil, :tobacco_id=>"8"} missing required keys: [:id]
Looking at this, I have to do something in the Tobaccos # show, but I canβt think of that.
I'm almost home and dry, you see what I did wrong? Thanks:)
TWO UPDATE NUMBER show.html.erb This is not an entire page to display, but it is an important part
<% if @reviews.blank? %> <h3>No reviews yet! Would you like to be the first?</h3> <%= link_to "Write Review", new_tobacco_review_path(@tobacco), class: "btn btn-danger" %> <% else %> <% @reviews.each do |review| %> <div class="reviews"> <p><%= review.comment %></p> <p><%= review.user.name %></p> <%= link_to "Edit", edit_tobacco_review_path(@tobacco, @review) %> </div> <% end %> <%= link_to "Write Another Review", new_tobacco_review_path(@tobacco), class: "btn btn-danger" %> <% end %>
UPDATE NUMBER 3 edit.html.erb
<%= form_for([@tobacco, @tobacco.reviews.build]) do |f| %> <%= render 'fields', f: f %> <%= f.submit "Update Review", class: 'btn btn-primary' %> <% end %> <%= link_to "Back", tobacco_path(@tobacco), class: "btn btn-default btn-block margin-top-25" %>
_fields.html.erb
<%= f.label :rating %> <%= f.select :rating, [['1', 1], ['2', 2], ['3', 3], ['4', 4], ['5', 5] ] ,class: 'form-control' %> <%= f.label :comment %> <%= f.text_field :comment, class: 'form-control' %>