Deleting Nested Reviews Deletes the whole Post Created - ruby-on-rails

I am setting a nested review scaffold inside the Post scaffold however, when i try to delete a review that is nested inside the show page in the Post, The whole post is deleted. how can i delete only the reviews without the post?
here's my code:
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user! , except: [:index,:show]
before_filter :check_user, only: [:edit,:update,:destroy]
# GET /posts
# GET /posts.json
def search
if params[:search].present?
#posts = Post.search(params[:search])
else
#posts = Post.all
end
end
def index
if params[:tag]
#posts = Post.tagged_with(params[:tag])
else
#posts = Post.all
end
end
# GET /posts/1
# GET /posts/1.json
def show
#reviews = Review.where(post_id: #post.id)
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
#post.user_id = current_user.id
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to root_url, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :description,:image,:all_tags)
end
def check_user
if current_user.id != #post.user_id
redirect_to root_path , alert: "Sorry this Post belongs to someone else"
end
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :posts do
collection do
get 'search'
end
resources :reviews , except: [:show,:index] do
member do
get "like" => "reviews#upvote"
get "dislike" => "reviews#downvote"
end
end
end
get 'pages/help'
get 'pages/blog'
get 'pages/contact'
get 'pages/tour'
resources :posts
root 'posts#index'
get 'tags/:tag', to: 'posts#index', as: "tag"
end
reviews_controller.rb
class ReviewsController < ApplicationController
before_action :set_review, only: [ :edit, :update, :destroy, :upvote,:downvote]
before_action :set_post
before_action :authenticate_user!
respond_to :html
def new
#review = Review.new
respond_with(#review)
end
def edit
end
def create
#review = Review.new(review_params)
#review.user_id = current_user.id
#review.post_id = #post.id
#review.save
redirect_to post_path(#post)
end
def update
#review.update(review_params)
respond_with(#post)
end
def destroy
#review.destroy
respond_with(#review)
end
def upvote
#review.upvote_from current_user
redirect_to :back
end
def downvote
#review.downvote_from current_user
redirect_to :back
end
private
def set_review
#review = Review.find(params[:id])
end
def set_post
unless #post = Post.where(id: params[:post_id]).first
redirect_to posts_path, flash: {alert: "Post doesn't exists"}
end
end
def review_params
params.require(:review).permit(:comment)
end
end
models/review.rb
class Review < ActiveRecord::Base
acts_as_votable
belongs_to :user
belongs_to :post
end
models/post.rb
class Post < ActiveRecord::Base
searchkick
has_many :reviews , dependent: :destroy
has_many :taggings
has_many :tags, through: :taggings
#Paperclip Installation
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
def all_tags=(names)
self.tags = names.split(",").map do |name|
Tag.where(name: name.strip).first_or_create!
end
end
def all_tags
self.tags.map(&:name).join(", ")
end
def self.tagged_with(name)
Tag.find_by_name!(name).posts
end
end
views/posts/index.html.erb
<table class="table">
<thead>
<tr>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><h4><%=link_to post.title , post%></h4></td>
<td><%=raw tag_links(post.all_tags)%></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<%end%>
</tbody>
</table>
<%= link_to 'new post', new_post_path %>
views/posts/show.html.erb
<div class="center">
<div class="right-align">
<h2><%= #post.title %></h2>
<hr>
</div>
<%if #post.image.exists?%>
<%= image_tag #post.image.url(:medium) %>
<%end%>
<div class="right-align">
<%= markdown #post.description %>
<br>
<table class="table table-bordered">
<tbody>
<% #reviews.each do |review|%>
<tr>
<td >
Welcome back <%= current_user.name %>
<h4><%= link_to "like" ,like_post_review_path(#post, review) , class: " btn btn-primary glyphicon glyphicon-chevron-up"%></h4>
<p><%= review.get_upvotes.size%></p>
<p><%= review.get_downvotes.size%></p>
<h4><%= link_to "Dislike" , dislike_post_review_path(#post, review) , class: "btn btn-primary glyphicon glyphicon-chevron-down"%></h4>
<p><%= markdown review.comment %></p>
<p><%= link_to "Edit", edit_post_review_path(#post, review) %></p>
<p><%= link_to 'Destroy', #review, method: :delete, data: { confirm: 'Are you sure?' } %></p>
</td>
</tr>
<%end%>
</tbody>
</table>
<p><%= link_to 'Write Review', new_post_review_path(#post) , class: "btn btn-primary" %></p>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Back', posts_path %>
</div>
</div>
Update:
i tried changing the code as suggested in the destroy method and in the Reviews Controller and the Post Show page but still getting the error. Here's the error i am getting :

Look like a typo, change:
<p><%= link_to 'Destroy', #review, method: :delete, data: { confirm: 'Are you sure?' } %></p>
to:
<p><%= link_to 'Destroy', review, method: :delete, data: { confirm: 'Are you sure?' } %></p>
and change your reviews controller destroy:
def destroy
#review.destroy
redirect_to :back
end

Related

How to get value from other class in Rails

I'm not sure if I am phrasing this question correctly. I am using the Stripe API for a Harry Potter themed Rails online store demo app. I followed the Stripe boilerplate code, so I currently have the amount set at a hardcoded value of $1.00. In my shopping cart, there is a method that displays the total cost of all items in the cart. That works fine, but I can't figure out how to pass that value to the Charges controller so that it sets that as the amount of the payment.
I'm fairly new to Rails, so any helpful explanations would be greatly appreciated.
Here is my charges/new.html.erb file:
<%= form_tag charges_path do %>
<article>
<% if flash[:error].present? %>
<div id="error_explanation">
<p><%= flash[:error] %></p>
</div>
<% end %>
<label class="amount">
<span>Amount: $1.00</span>
</label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="100"
data-locale="auto"></script>
<% end %>
Here is my Charges controller:
class ChargesController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create]
def new
end
def create #METHOD IS CALLED AFTER PAYMENT IS MADE
# Amount in cents
#amount = 100
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => 'Witch or Wizard',
:currency => 'usd'
)
Cart.destroy(session[:cart_id])
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
Here is my carts/show.html.erb file:
<p id="notice"><%= notice %></p>
<h2>My Cart</h2>
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Total Price in Galleons</th>
<th>Total Price in Muggle Currency</th>
</tr>
<tbody>
<%= render(#cart.line_items) %>
<tr>
<td>Total</td>
<td><%= number_to_currency(#cart.total_price * 7.35) %></td>
<td></td>
<td></td>
</tr>
</tbody>
</thead>
</table>
<br>
<div class="row">
<div class="col-md-3">
<div class="row">
<div class="col-md-4">
<%= link_to 'Back', products_path, :class => 'btn btn-primary whiteText' %>
</div>
<div class="col-md-4">
<%= link_to "Checkout", new_charge_path, :class => 'btn btn-success whiteText' %>
</div>
<div class="col-md-4">
<%= link_to 'Empty Cart', #cart, method: :delete, data: {confirm: 'Are you sure you want to empty your cart?'}, :class => 'btn btn-danger whiteText' %>
</div>
</div>
</div>
<div class="col-md-9"></div>
</div>
Here is my Carts controller:
class CartsController < ApplicationController
before_action :set_cart, only: [:show, :edit, :update, :destroy]
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart
# GET /carts
# GET /carts.json
def index
#carts = Cart.all
end
# GET /carts/1
# GET /carts/1.json
def show
end
# GET /carts/new
def new
#cart = Cart.new
end
# GET /carts/1/edit
def edit
end
# POST /carts
# POST /carts.json
def create
#cart = Cart.new(cart_params)
respond_to do |format|
if #cart.save
format.html { redirect_to #cart, notice: 'Cart was successfully created.' }
format.json { render :show, status: :created, location: #cart }
else
format.html { render :new }
format.json { render json: #cart.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /carts/1
# PATCH/PUT /carts/1.json
def update
respond_to do |format|
if #cart.update(cart_params)
format.html { redirect_to #cart, notice: 'Cart was successfully updated.' }
format.json { render :show, status: :ok, location: #cart }
else
format.html { render :edit }
format.json { render json: #cart.errors, status: :unprocessable_entity }
end
end
end
# DELETE /carts/1
# DELETE /carts/1.json
def destroy
#cart.destroy if #cart.id == session[:cart_id]
session[:cart_id] = nil
respond_to do |format|
format.html { redirect_to root_path, notice: 'Cart was emptied.' }
format.json { head :no_content }
end
end
def update_quantity
#line_item.update_attribute(:quantity)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_cart
#cart = Cart.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def cart_params
params.fetch(:cart, {})
end
def invalid_cart
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to root_path, notice: 'Invalid cart'
end
end
Here is my Cart model:
class Cart < ApplicationRecord
has_many :line_items, dependent: :destroy
def add_product(product)
current_item = line_items.find_by(product_id: product.id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product.id)
end
current_item
end
def total_price
line_items.to_a.sum {|item| item.total_price}
end
def convert_to_muggle(galleons)
line_items.to_a.sum {|item| item.convert_to_muggle}
end
end
And here is my routes file:
Rails.application.routes.draw do
resources :charges
resources :orders
resources :line_items
resources :carts
devise_for :users
match 'users/:id' => 'users#destroy', :via => :delete, :as => :admin_destroy_user
resources :users, only: [:index, :show, :edit, :update]
root 'products#index'
resources :products
controller :products do
post '/products/destroy' => 'products#destroy', as: :destroy
get '/products/add_to_cart' => 'products#add_to_cart', as: :add_to_cart
get '/products/remove_from_cart' => 'products#remove_from_cart', as: :remove_from_cart
end
controller :line_items do
post '/line_items/increase_quantity' => 'line_items#increase_quantity', as: :increase_quantity
end
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
In your charges_controller, change the amount:
#amount = #cart.total_price * 735
And your charges/new.html.erb:
<span>Amount: <%= number_to_currency(#cart.total_price * 7.35) %></span>
and
data-amount="<%= #cart.total_price * 735 %>"
Let me know if that helps.

Acts As Votable Get Upvotes Error

Working with the Acts as Votable gem on my rails 4 app.
So far I have gotten everything working, except when I call get_upvotes and get_downvotes to display how many votes a post has, I get this error:
undefined method `get_upvotes' for #<Post:0x000001078b5f58>
Here is my Post view (_post.html.erb):
<%= post.name %>
<%= post.title %>
<%= post.content %><br>
<%= link_to 'Show', post %>
<% if can? :update, #post %>
<%= link_to 'Edit', edit_post_path(post) %>
<% end %>
<% if can? :destroy, #post %>
<%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
<%= link_to like_post_path(post), class: "like", method: :put do %>
<button type="button" class="btn btn-info" aria-label="Left Align">
<span class="glyphicon glyphicon-thumbs-up glyphicon-align-center" aria-hidden="true"></span>
<span class="badge"><%= post.get_upvotes.size %></span>
</button>
<% end %>
<%= link_to dislike_post_path(post), class: "like", method: :put do %>
<button type="button" class="btn btn-info" aria-label="Left Align">
<span class="glyphicon glyphicon-thumbs-down glyphicon-align-center" aria-hidden="true"></span>
<span class="badge"><%= post.get_downvotes.size %></span>
</button>
<% end %>
Here is my controller (posts_controller.rb):
class PostsController < ApplicationController
load_and_authorize_resource
before_action :set_post, only: [:show, :edit, :update, :destroy, :upvote, :downvote]
def index
end
def show
end
def new
end
def edit
end
def create
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
def upvote
#post = Post.find(params[:id])
#post.upvote_from current_user
redirect_to :back
end
def downvote
#post = Post.find(params[:id])
#post.downvote_from current_user
redirect_to :back
end
private
def set_post
#post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:name, :title, :content, :image, :image2, :video1, :video2)
end
end
and my model (post.rb):
class Post < ActiveRecord::Base
acts_as_voter
belongs_to :user
end
user model (user.rb):
class User < ActiveRecord::Base
acts_as_votable
has_many :posts
end
and lastly my routes (routes.rb):
resources :posts do
member do
put "like" => "posts#upvote"
put "dislike" => "posts#downvote"
end
end
Does anyone know why get_upvotes isn't working?
Reading the docs, it looks like get_upvotes is a method on the acts_as_votable, not the acts_as_voter.
I don't know much about the context of your code, but shouldn't the User be voting on the Post, like so:
class Post < ActiveRecord::Base
acts_as_votable
belongs_to :user
end
User model:
class User < ActiveRecord::Base
acts_as_voter
has_many :posts
end
See: https://github.com/ryanto/acts_as_votable#votable-models

How to link to a nested route action inside a parent loop?

I'm trying to display everything on my index page, but when I try to link to a new_story_substory_path I get undefined local variable or method substory.
Here is the code:
index.html.erb
<% #stories.each do |story| %>
<h3><p><%= story.title %></p></h3>
<p><%= story.plot %></p>
<% if story.user == current_user %>
<%= link_to 'Show XXX', story_path(story), class: "btn btn-success" %>
<%= link_to 'Edit', edit_story_path(story), class: "btn btn-success" %>
<%= link_to "Delete", story_path(story), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-success" %></br>
<% end %>
<% story.substories.each do |substory| %>
<h4><p><%= substory.title %></p></h3>
<p><%= substory.subplot %></p>
<% if story.user == current_user %>
<%= link_to 'Show', story_substory_path(substory.story, substory), class: "btn btn-default" %>
<%= link_to 'Edit', edit_story_substory_path(substory.story, substory), class: "btn btn-default" %>
<%= link_to "Delete", story_substory_path(substory.story, substory), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-default" %>
<% end %>
<% end %>
<br>
<% if story.user == current_user %>
<br>
<br>
# this is where I'm getting the error:
<%= link_to 'New subplot', new_story_substory_path(substory.story, substory), class: "btn btn-warning" %>
# however if I move this up, inside the second loop, it works perfectly.
<br>
<% end %>
<% end %>
<br>
<%= link_to 'New Story', new_story_path, class: "btn btn-danger" %>
Here is my controller, routes and models:
class StoriesController < ApplicationController
before_action :set_story, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#stories = Story.all
end
def show
end
def new
#story = current_user.stories.build
end
def edit
end
def create
#story = current_user.stories.build(story_params)
respond_to do |format|
if #story.save
format.html { redirect_to root_path, notice: 'Story was successfully created.' }
format.json { render :show, status: :created, location: root_path }
else
format.html { render :new }
format.json { render json: root_path.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #story.update(story_params)
format.html { redirect_to root_path, notice: 'Story was successfully updated.' }
format.json { render :show, status: :ok, location: root_path }
else
format.html { render :edit }
format.json { render json: #story.errors, status: :unprocessable_entity }
end
end
end
def destroy
#story.destroy
respond_to do |format|
format.html { redirect_to stories_url, notice: 'Story was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_story
#story = Story.find(params[:id])
end
def story_params
params.require(:story).permit(:title, :plot)
end
end
Rails.application.routes.draw do
devise_for :users
resources :stories do
resources :substories
end
root 'stories#index'
end
class Story < ActiveRecord::Base
has_many :substories, dependent: :destroy
belongs_to :user
end
class Substory < ActiveRecord::Base
belongs_to :story
belongs_to :user
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :stories, dependent: :destroy
has_many :substories, dependent: :destroy
end
what am I missing?
Edit:
Here is the controller for the substories:
class SubstoriesController < ApplicationController
before_action :set_substory, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
before_action :set_story
def index
#Substories = #story.substories.all
end
def show
end
def new
#substory = Substory.new
end
def edit
end
def create
#substory = Substory.new(substory_params)
#substory.user_id = current_user.id
#substory.story_id = #story.id
if
#substory.save
redirect_to #story
else
render 'new'
end
end
def update
respond_to do |format|
if #substory.update(substory_params)
format.html { redirect_to root_path, notice: 'Story was successfully updated.' }
format.json { render :show, status: :ok, location: root_path }
else
format.html { render :edit }
format.json { render json: #story.errors, status: :unprocessable_entity }
end
end
end
def destroy
#substory.destroy
redirect_to root_path
end
private
def set_story
#story = Story.find(params[:story_id])
end
def set_substory
#substory = Substory.find(params[:id])
end
def substory_params
params.require(:substory).permit(:title, :subplot)
end
end
I am trying to put this as a comment but I need 50 reputation points to do so. Anyway here is my solution:
The problem is index.html comes from Stories Controller. At this point, you are actually not using any other controllers. This is a common problem at a single page application using ROR. Things do get messy this way.
And you are right, you have to move your error on the second loop. The problem is it would show more than once. That is because there is more than one story. If you want to avoid this, the solution I would say is just make an stories#show show.html.erb. Once you click story, it directs to substroy which then has a plot.
I got the answer from the comments.
MrYoshi wrote:
At the line producing the error: You are calling the substory variable but it is only existing in the story.substories.each loop ; you probably meant to use new_story_substory_path(story) (path leading to the creation page of a substory belonging to the story currently been seen/edited)
Basically I changed the line form:
<%= link_to 'New subplot', new_story_substory_path(substory.story, substory), class: "btn btn-warning" %>
to:
<%= link_to 'New subplot', new_story_substory_path(story), class: "btn btn-warning" %>
This works!

Association between Post and Location

This my first ruby on rails application.
Model Location and Post, Location has many post.I create location as tree structure with ancestry gem.
class Post < ActiveRecord::Base
belongs_to :location, :counter_cache => true
end
class Location < ActiveRecord::Base
include Tree
has_ancestry :cache_depth => true
has_many :posts
end
This my Post Controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all
end
def show
end
def new
#post = Post.new
end
def edit
end
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render action: 'show', status: :created, location: #post }
else
format.html { render action: 'new' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
private
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:name, :location_id)
end
end
Creating Post with location in Post _form.html.erb
<%= simple_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 |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.input :name %>
<%= f.select :location_id, Location.all.at_depth(4) { |l| [ l.name, l.id ] } %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My question are
First question- f.select :location_id , how display location name, not location id, i am using with simple form
Second question- Post index got error in <%= post.location.name %>
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= post.location.name %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %> </td>
</tr>
<% end %>
First question:
Check the simple_form syntax for a dropdown. It is mentioned in the docs and you should be able to get this working by yourself.
Second question:
Does the offending post really have a related location? If it does not have one, it can not display the name of course. To counter these nil errors, use try:
<%= post.location.try(:name) %>
try will call the method name on location only if location is not nil.
For your first question :
Maybe you should read about "options_for_select"
http://guides.rubyonrails.org/form_helpers.html#option-tags-from-a-collection-of-arbitrary-objects
<% cities_array = City.all.map { |city| [city.name, city.id] } %>
<%= options_for_select(cities_array) %>
For your second question:
What is your error ?
Maybe one of your "post.location" is nil.
If so, try:
post.location.name unless post.location.nil?
Hope this can help

Bugs after deployment

If you take a look at the project here: http://www.leapfm.com/ you can scroll down and click More on the front page and it works. However, if you try doing that in New Songs tab it stays at 'Page is loading...'. I'm not quite sure why this is.
new_songs.html.erb
<div id="new_songs">
<%= render 'new_songs'%>
</div></div>
_new_songs.html.erb (partial)
<div id="layout-1">
<!--div class="left-side"> -->
<%#= will_paginate #songs %>
<h6>New songs</h6>
<hr>
<ol><% #songs.each do |song| %>
<span class="title">
<li><%= link_to song.title, song %><span class="subtext"> (<%= song.url %>)<br></li></span>
<%#=link_to '&#9660'.html_safe, vote_against_song_path(song), :remote => true, :method => :put %>
posted <%= time_ago_in_words(song.created_at) + " ago" %>
<small><span class="comments"></small> | <%= pluralize(song.comments.size, 'comment') %></span></small><br /></span>
<%#= link_to 'Show', song, class: "button small secondary" %>
<%= link_to('Edit', edit_song_path(song), class: "button small secondary") if can? :update, song %>
<%= link_to('Destroy', song, method: :delete, data: {confirm: 'Are you sure?'}, class: "button small secondary") if can? :destroy, song %>
<% end %>
</ol>
</div>
<div class="pagination-centered">
<ul class="pagination">
<%#= will_paginate #songs %>
<!-- or custom pagination -->
<% if #songs.previous_page %>
<%= link_to "Back", params.merge(page: #songs.previous_page) %>
<% end %>
<% if #songs.next_page %>
<%= link_to "More", params.merge(page: #songs.next_page) %>
<% end %>
</ul></div>
pagination.js
$(function() {
$(".pagination a").on("click", function() {
$(".pagination").html("Page is loading...");
$.getScript(this.href);
return false;
});
});
song_controller.rb
class SongsController < ApplicationController
before_filter :authenticate_user!, only: [:create ,:edit, :update, :destroy, :vote_for_song]
before_action :set_song, only: [:show, :edit, :update, :destroy, :vote_for_song]
def extract_video
#song = Song.find(params[:id])
#song.YouTubeAddy.extract_video_id
end
def vote_for
#song = Song.find(params[:id])
current_user.vote_for(#song)
#song.plusminus = #song.votes_for
#song.save
respond_to do |format|
format.js { render 'update_votes' }
end
end
def vote_against
#song = Song.find(params[:id])
current_user.vote_against(#song)
respond_to do |format|
format.js { render 'update_votes' }
end
end
def new_songs
#songs = Song.order("id DESC").paginate(:page => params[:page], :per_page => 15)
end
# GET /Songs
# GET /Songs.json
def index
if params[:genre]
#songs = Song.tagged_with(params[:genre]).paginate(:page => params[:page], :per_page => 15)
else
#songs = Song.order('plusminus').paginate(:page => params[:page], :per_page => 15)
end
end
# GET /Songs/1
# GET /Songs/1.json
def show
#comment = Comment.new(song: #song)
#video_tag = YouTubeAddy.extract_video_id(#song.url)
end
# GET /Songs/new
def new
#song = Song.new
end
# GET /Songs/1/edit
def edit
end
# POST /Songs
# POST /Songs.json
def create
#song = Song.new(song_params)
respond_to do |format|
if #song.save
format.html { redirect_to #song, notice: 'Song was successfully created.' }
format.json { render action: 'show', status: :created, location: #song }
else
format.html { render action: 'new' }
format.json { render json: #song.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /Songs/1
# PATCH/PUT /Songs/1.json
def update
respond_to do |format|
if #song.update(song_params)
format.html { redirect_to #song, notice: 'Song was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #song.errors, status: :unprocessable_entity }
end
end
end
# Song /Songs/1
# Song /Songs/1.json
def destroy
#song.destroy
respond_to do |format|
format.html { redirect_to songs_url }
format.json { head :no_content }
end
end
private
def set_song
#song = Song.find(params[:id])
end
def song_params
params.require(:song).permit(:title, :artist, :url, :track, :user_id, :tag_list)
end
end
you are placing js code for 2 actions in the same file.
you have index action and new_songs action in songs_controller.rb, and you put your js in index.js.erb:
$("#songs").html("<%= escape_javascript(render("songs")) %>");
$("#new_songs").html("<%= escape_javascript(render("new_songs")) %>");
move the second line in a file called new_songs.js.erb and you are done.

Resources