Undefined method :name when showing listing (ruby on rails) - html

I created a user profile page that shows all the listings the user made. Each listing has a 'show' link that links to a new page that shows the listing individually on a different page. I got this to work for the user profile page.
I'm using this link
<li><%= link_to "Show", user_listing_path(name: #user.name, id: listing.id) %></li>
However, now I want to create a listings index page that shows all listings of every user. Each listing again should have a 'show' link that links to a page that shows the listing individually. The same link that worked on the user profile page does not work on the listing index page.
I get the following error undefined method `name' for nil:NilClass
and it points to
<%= link_to "Show", user_listing_path(name: #user.name, id: listing.id) %>
Does anyone know why?
User show file (show.html.erb)
<div class= "showuser">
<div class="error-message">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
</div>
<h4>
<%= gravatar_for #user %>
<%= #user.name %>
</h4>
<div class="span 8">
<% if #user.listings.any? %>
<h3> Job Posts (<%= #user.listings.count %>)</h3>
<ol class="listings">
<%= render #listings %>
<% #listings.each do |listing| %>
<% end %>
</ol>
<%= will_paginate #listings %>
<% end %>
</div>
</div>
listing file (_listing.html.erb)
<li>
<h4><%= listing.title %></h4>
<p><%= listing.location %></h4><br>
<span class="content"><%= listing.description %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(listing.created_at) %> ago
</span>
<li><%= link_to "Show", user_listing_path(name: #user.name, id: listing.id) %></li>
<% if current_user?(listing.user) %>
<li><%= link_to "Edit", edit_listing_path %></li>
<%= link_to "delete", listing, method: :delete,
data: { confirm: "You sure?" },
title: listing.description %>
<% end %>
</li>
listing controller
class ListingsController < ApplicationController
before_action :signed_in_user, only: [:create, :destroy, :edit, :update]
before_action :correct_user, only: [:destroy, :edit, :update]
def create
#listing = current_user.listings.build(listing_params)
if #listing.save
flash[:success] = "Job Post created"
redirect_to current_user
else
render 'listings/new'
end
end
def edit
end
def update
if #listing.update_attributes(listing_params)
flash[:success] = "Listing updated"
redirect_to #listing
else
render 'edit'
end
end
def show
#user = User.find_by_name(params[:name])
#listing = Listing.find_by_id(params[:id])
end
def new
#listing = Listing.new
#listings = Listing.paginate(page: params[:page])
end
def destroy
#listing.destroy
redirect_to current_user
end
def index
#listings = Listing.all
#listings = Listing.paginate(page: params[:page])
#user = User.find_by_name(params[:name])
#listing = Listing.find_by_id(params[:id])
end
private
def listing_params
params.require(:listing).permit(:description, :location, :title)
end
def correct_user
#listing = current_user.listings.find_by(id: params[:id])
redirect_to current_user if #listing.nil?
end
end
listing show file (show.html.erb) Shows listing indivudally
<div class="show_listing">
<div class="col-md-6">
<div class="col-md-6">
<h3><%= #listing.title %></h3>
<h3><%= #listing.location %></h3>
<p><%= #listing.description %></p><br>
<div class="center">
<%= link_to "Apply Now", '#', class: "btn btn-info", data: {no_turbolink: true} %>
</div>
</div>
</div>
</div>
<div class="show_link_position">
<% if current_user == #listing.user %>
<%= link_to 'Edit', edit_listing_path, class: "btn btn-link" %> |
<% end %>
<%= link_to 'Back', current_user, class: "btn btn-link" %>
</div>
listing index file (index.html.erb)
<div class="top">
<div class="categories-container">
<div class="boxed grid-3 category-link ">
<li><%= link_to "Find Jobs", findjobs_path, class: "category-link"%></li>
<li><%= link_to "Post Jobs", new_path, class: "category-link" %></li>
<li><%= link_to "Find Jobs", findjobs_path, class: "category-link" %></li>
<li><%= link_to "Post Jobs", new_path, class: "category-link" %></li>
<li><%= link_to "Find Jobs", findjobs_path, class: "category-link" %></li>
<li><%= link_to "Post Jobs", new_path, class: "category-link" %></li>
<li><%= link_to "Find Jobs", findjobs_path, class: "category-link" %></li>
<li><%= link_to "Post Jobs", new_path, class: "category-link" %></li>
</div>
</div>
<div class="table-container">
<div class= "grid-8 grid-moved">
<% #listings.each do |listing| %>
<h4><%= listing.title %></h4>
<h5> <%= listing.user.name %>, Posted <%= time_ago_in_words(listing.created_at) %> ago</h5>
<h5>Job Description:</h5>
<p><%= listing.description %></p>
<p>Location: <%= listing.location %></p>
<li><%= link_to "Show", user_listing_path(name: #user.name, id: listing.id) %></li>
<br><hr><br>
<% end %>
</div>
</div>
<div class="container">
<div class="pagination">
<%= will_paginate #listings %>
</div>
</div>
routes
Rails.application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
resources :listings
root 'static_pages#home'
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via:'delete'
match '/help', to: 'static_pages#help', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match '/about', to: 'static_pages#about', via: 'get'
match '/new', to: 'listings#new', via: 'get'
match '/users/:name/:id', to: 'listings#show', via: :get, as: :user_listing
match '/findjobs', to: 'listings#index', via: 'get'
Let me know if I forgo any important information.

You have not defined #user in the controller.
In the next line, you appropriately access the listing user, as follows:
<% if current_user?(listing.user) %>
You simply need to adjust your code to look like:
<li><%= link_to "Show", user_listing_path(name: listing.user.name, id: listing.id) %></li>
Make sense?

Try:
<li><%= link_to "Show", user_listing_path(#user, listing) %></li>
And on your controller:
def show
#user = User.find(params[:id)
#listing = Listing.find(params[:id])
end

Related

I'm having trouble displaying comments on my Rails Blog

I'm currently working on my Rails Blog. While the development is coming along nicely, I've hit a roadblock in the comment.
Every time I try to leave a test comment, I always get "rollback transaction" just before the comment gets saved.
Here's what happens when I create a comment.
Here's the code for looking at blog entry:
post/show.html.erb
<h1 class="title">
<%= #post.title %>
</h1>
<h2>Authored by:
<%= #post.user.username%>
</h2>
<p>
<%=raw #post.content %>
</p>
<div class="comments">
<h3 class="is-3">Comments</h3>
<%if #post.comments.count == 0%>
<strong>There are no comments on this post. Feel free to send one!</strong><br/>
<% else %>
<%= render #post.comments %>
<% end %>
<%if !user_signed_in? %>
<strong>Yo, if you wanna comment on my site, either <%= link_to 'Sign up', new_user_registration_path %> or <%= link_to 'Log in', new_user_session_path %></strong>
<% else %>
<%= render partial: "comments/form", locals: {comment: #post.comments.new} %>
<% end %>
</div>
</div>
<br>
<% if user_signed_in? %>
<div class="functions">
<%= link_to "Update", edit_post_path(#post) if policy(#post).update? do%>
<i class="fa fa-edit editpage fa-3x"></i>
<% end %>
<%= link_to "Delete", #post, :confirm => "Are you sure you want to delete this post?", :method => :delete if policy(#post).destroy? do%>
<i class="fa fa-trash deletepage fa-3x"></i>
<% end %>
</div>
<% end %>
<%= link_to 'Back to the main page', root_path %>
In case you're curious, here's what the comment partial looks like:
<strong><%= #post.comment.user.username %> says:</strong><br>
<%=#post.comment.content %>
<p>
<=time_ago_in_words(comment.created_at) %>
</p>
Can anyone help me figure out why is it that when I create a comment, it rolls back the transaction? I'll provide more information if required.
Edit: Here's the Comments Controller for my rails blog.
class CommentsController < ApplicationController
before_action :set_post
def create
set_post
# Create associated model, just like we did in the console before
#comment = #post.comments.create(comment_params)
# We want to show the comment in the context of the Post
#comment.post_id = #post.post_id
#comment.user_id = current_user.user_id
#comment.save
redirect_to #post
end
def update
#comment = set_comment
#comment.update(comment_params)
redirect_to #post
end
def destroy
#comment = set_comment
#comment.destroy
redirect_to #post
end
private
def comment_params
params.require(:comment).permit(:content)
end
def set_post
#post = Post.friendly.find(params[:post_id])
end
def set_comment
#comment = Comment.find(params[:id])
end
end
Comment Model:
class Comment < ApplicationRecord
belongs_to :post
belongs_to :user
end
Also, the Comment form
<strong><%= #post.comment.user.username %> says:</strong><br>
<%=#post.comment.content %>
<p><= time_ago_in_words(comment.created_at) %></p>

Missing template error in rails

new.html is a registration form ,which creates tutor account .
It involves error handling . _error_messages.html.erb is the file which handles the error ,like should be filling in all text fields .
e.g , showing :
`
The form contains 3 errors.
Name can't be blank
Password confirmation can't be blank
Password confirmation doesn't match Password
However ,when submits the form without any input in new.html ,it shows the error
Missing template tutors/register, application/register with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in: * "C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/web-console-2.0.0/lib/action_dispatch/templates" * "D:/Sites/abc/app/views"
new.html.erb
<% provide(:title, 'Registeration') %>
<h1>Tutor Registration</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#tutor) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.label :gender %>
<%= f.select(:gender, ['Male', 'Female'] , class: 'form-control' )%>
<%= f.label :tutor_education_level %>
<%= f.select(:education_level, ['Bachelor', 'Master', 'Doctor'] , class: 'form-control' )%>
<%= f.label :tutor_institution %>
<%= f.text_field :institution, class: 'form-control' %>
<%= f.label :tutorial_experience %>
<%= f.text_field :experience, class: 'form-control' %>
<%= f.label :tutor_preferred_district %>
<%= f.text_field :district, class: 'form-control' %>
<%= f.label :tutor_preferred_subject %>
<%= f.text_field :subject, class: 'form-control' %>
<%= f.label :tutor_required_student_level %>
<%= f.select(:student_level, ['P1-P3', 'P4-P6', 'S1-S3', 'S4-S6'] , class: 'form-control' )%>
<%= f.submit "Create tutor's account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
views/shared/_error_messages.html.erb
<% if #tutor.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(#tutor.errors.count, "error") %>.
</div>
<ul>
<% #tutor.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
Tutor -controller
class TutorsController < ApplicationController
before_action :logged_in_tutor, only: [:edit, :update]
before_action :correct_tutor, only: [:edit, :update]
def index
#tutors = Tutor.all
end
def show
#tutor = Tutor.find(params[:id])
end
def new
#tutor = Tutor.new
end
def create
#tutor = Tutor.new(tutor_params)
if #tutor.save
log_in #tutor
flash[:success] = "Congratulations! Your registration is successful!"
redirect_to #tutor
else
render 'register'
end
end
def edit
#tutor = Tutor.find(params[:id])
end
def update
if #tutor.update_attributes(tutor_params)
flash[:success] = "Profile updated successfuly!"
redirect_to #tutor
else
render 'edit'
end
end
# Handle sign-up failure, to redirect the tutor to the registeration form again
def tutor_params
params.require(:tutor).permit(:name, :email, :password, :password_confirmation, :address,:gender ,:education_level,:institution,:exprience,:district,:subject,:student_level)
end
def logged_in_tutor
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
def correct_tutor
#tutor = Tutor.find(params[:id])
redirect_to(root_url) unless current_tutor?(#tutor)
end
end
When you submit the form, request sends to the create action:
def create
#tutor = Tutor.new(tutor_params)
if #tutor.save
# if #tutor valid save it and redirect to show action
redirect_to #tutor
else
# else render the register template(or action)
render 'register'
end
end
In the create action there is a conditional if, in the first case all is good, #tutor has been saved and Rails call redirect to show action, otherwise Rails trying to render register template which is not exists(the errors claims about it). To resolve that issue create register template with desired html code which should run if #tutor isn't saved.

Rails using checkbox for adding tags to posts ( many to many )

I have a Post model and Tag model with many to many relationships.
Post Model:
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
end
Tag model:
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
I also have a join table for posts_tags :
class JoinPostsAndTags < ActiveRecord::Migration
def change
create_table :posts_tags do |t|
t.integer :tag_id
t.integer :post_id
t.timestamps null: false
end
end
end
Now, I need to provide multiple selection for selecting tags for a post.
Below is the post form.html.erb
<%= form_for #post do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :Name %><br>
<%= f.text_field :Name %>
</div>
<div class="field">
<%= f.label :Email %><br>
<%= f.text_field :Email %>
</div>
<div class="field">
<%= f.label :Message %><br>
<%= f.text_area :Message %>
</div>
<% #tags= Tag.all %>
<% if #tags %>
<% #tags.each do |tag| %>
<div>
<%= check_box_tag "post[tag_ids][]", tag.id, #post.tags.include?(tag) %>
<%= tag.name %>
</div>
<% end %>
<% end %>
<br><br>
<%= link_to 'Create Tag', tags_path %>
<br><br>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
It is not adding the selected tags to the post. I need to add the selected tags to the post. How can I do it.
But, in rails console if I use post= Post.first tag= Tag.first post.tags<<tag it adds the tag to the post.
I don't have any special code in post controller to handle this. Please help me.
Add {tag_ids:[]} to your params permit arguments in your PostsController, like so:
def post_params
params.require(:post).permit(:name, :email, :message, {tag_ids:[]})
end

Audio has contents that are not what they are reported to be - Paperclip

A beginner in Ruby here!
I am trying to create a Soundcloud clone on ruby.
When I try to upload an audio file i get the error:
1 error prohibited this song from being saved:
Audio has contents that are not what they are reported to be
controller: song.rb
class Song < ActiveRecord::Base
belongs_to :user
has_attached_file :audio,
:url => "/assets/:class/:id/:attachment/:basename.:extension",
:path => ":rails_root/public/assets/:class/:id/:attachment/:basename.:extension"
validates_attachment :audio,
:content_type => { :content_type => ["audio/mpeg", "audio/mp3"] },
:file_name => { :matches => [/mp3\Z/] }
_form.html.erb
<%= form_for(#song) do |f| %>
<% if #song.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#song.errors.count, "error") %> prohibited this song from being saved:</h2>
<ul>
<% #song.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :audio %><br>
<%= f.file_field :audio%>
</div>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Audio:</strong>
<%= #song.audio.url %>
</p>
<p>
<strong>Title:</strong>
<%= #song.title %>
</p>
<%= link_to 'Edit', edit_song_path(#song) %> |
<%= link_to 'Back', songs_path %>
In my experience with this problem, image data in the mp3's metadata (i.e. - an album cover) was the critical factor. The image data triggers the content type spoofing mechanism and the record will fail validation. To remove the image metadata, I opened the mp3 with Audacity, and exported it to a new file, which will not include image metadata because Audacity doesn't seem to include this automatically.

Assigning dom id based on model attributes in Rails nested form

I have a nested form.
Right now I want to arrange the layout with some CSS but I am facing trouble allocating dom ids to the form.
This is the subject controller.
I want to allocate lesson_type as seen in line 5 as the dom id.
1 def index
2 #subjects = Subject.all
3 #subject = Subject.new
4 lecture = #subject.lessons.build
5 lecture.lesson_type = "lecture"
lecture.lesson_groups.build
lecture.destroy
tutorial = #subject.lessons.build
tutorial.lesson_type = "tutorial"
tutorial.lesson_groups.build
tutorial.destroy
laboratory = #subject.lessons.build
laboratory.lesson_type = "laboratory"
laboratory.lesson_groups.build
laboratory.destroy
respond_to do |format|
format.html # index.html.erb
format.json { render json: #subjects }
format.js
end
end
The following is the form.
<%= nested_form_for(#subject, :remote=>true) do |f| %>
<% if #subject.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#subject.errors.count, "error") %> prohibited this subject from being saved:</h2>
<ul>
<% #subject.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :subject_code %><br />
<%= f.text_field :subject_code %>
</div>
<%= f.fields_for :lessons do |lesson| %>
<%= lesson.label :lesson_type %><br/>
<%= lesson.text_field :lesson_type, :readonly=>true%><br/>
<%= lesson.label :name %><br/>
<%= lesson.text_field :name %><br/>
<%= lesson.fields_for :lesson_groups do |lesson_group| %>
<%= lesson_group.label :group_index %><br/>
<%= lesson_group.text_field :group_index %>
<%= lesson_group.link_to_remove "Remove this task" %>
<% end %>
This is the div where I want to add an id to.
<%= f.fields_for :lessons do |lesson| %>
<%= lesson.label :lesson_type %><br/>
<%= lesson.text_field :lesson_type, :readonly=>true%><br/>
<%= lesson.label :name %><br/>
<%= lesson.text_field :name %><br/>
I have tried out the following but it did not worked.
<div id = "<%= :lesson_type%>">
Would appreciate it if someone could help me out thanks.
sorry..
#controller
def index
...
lecture.lesson_type = #lesson_dom_id = "lecture" # line 5
...
end
#view
<div id="<%= #lesson_dom_id %>">