Object in hidden_field_tag becomes nil when partial is called into an index (yet, works in individual Show view) - ruby-on-rails-3.1

Rails 3.1.3
I am making a simple site where people can share short stories and can rate those stories on a 5 Star rating system. The Star rating system is the problem. I can get it to work fine in the stories/show.html view, but not on the indexed home page. Here is my code:
home.html.erb
<% content_for(:scripts) do %>
<%= javascript_include_tag 'rating_ballot'%>
<% end %>
<div id="talesFeedHome">
<p class="notice"><%= notice %></p>
<%= render #tales.sort_by { |tale| tale.created_at }.reverse %>
</div>
<p class="clear"> </p>
tales/_tale.html.erb
<% if signed_in? %>
<div id="homeTales">
<ul>
<div id="taleShow">
<div id="controlPanel">
<li id="taleUserName"><%= tale.user.name %></li>
<li id="averageRating"> Your Rating:<br /><%= render "tales/stars" %></li>
</div>
<div id="taleDisplay">
<li><%= link_to(tale) do %>
<span><%= tale.title %> </span>
<span><%= tale.content %></span>
<% end %>
</li> <br />
</div>
</div>
</ul>
</div>
<% else %>
...
tales/_stars.html.erb
<div id="starRating">
<%= form_for(rating_ballot, :remote => true, :html => { :class => 'rating_ballot' }) do |f| %>
<%= f.label("value_1", content_tag(:span, '1'), {:class=>"rating", :id=>"1"}) %>
<%= radio_button_tag("rating[value]", 1, current_user_rating == 1, :class => 'rating_button') %>
<%= f.label("value_2", content_tag(:span, '2'), {:class=>"rating", :id=>"2"}) %>
<%= radio_button_tag("rating[value]", 2, current_user_rating == 2, :class => 'rating_button') %>
<%= f.label("value_3", content_tag(:span, '3'), {:class=>"rating", :id=>"3"}) %>
<%= radio_button_tag("rating[value]", 3, current_user_rating == 3, :class => 'rating_button') %>
<%= f.label("value_4", content_tag(:span, '4'), {:class=>"rating", :id=>"4"}) %>
<%= radio_button_tag("rating[value]", 4, current_user_rating == 4, :class => 'rating_button') %>
<%= f.label("value_5", content_tag(:span, '5'), {:class=>"rating", :id=>"5"}) %>
<%= radio_button_tag("rating[value]", 5, current_user_rating == 5, :class => 'rating_button') %>
<%= hidden_field_tag(:tale_id, #tale.id) %>
<% end %>
</div>
It is at this point, in the hidden field tag, that I get this error:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Here are the 3 relevant controllers:
pages_controller.rb
class PagesController < ApplicationController
def home
#tales = Tale.all
end
end
tales_controller.rb
class TalesController < ApplicationController
respond_to :html, :js
def new
#tale = Tale.new
end
def show
#tale = Tale.find(params[:id])
end
def index
#tales = Tale.all
#tale = Tale.find(params[:id])
end
...
ratings_controller.rb
class RatingsController < ApplicationController
before_filter :authenticate_user!
respond_to :html, :js
def create
#tale = Tale.find_by_id(params[:tale_id])
#rating = Rating.new(params[:rating])
#rating.tale_id = #tale.id
#rating.user_id = current_user.id
if #rating.save
respond_to do |format|
format.html { redirect_to #tale, :notice => "Your rating has been saved" }
format.js
end
end
end
def update
#rating = current_user.ratings.find_by_tale_id(params[:tale_id])
#tale = #rating.tale
if #tale and #rating.update_attributes(params[:rating])
respond_to do |format|
format.html { redirect_to #tale, :notice => "Your rating has been updated" }
format.js
end
end
end
end
The problem is here somewhere. Somehow when rendering #tales on the home page, this invalidates the #tale.id on the _stars partial. I can not figure out how to solve this. Thank You.

ok, I think your value of #tales is nil so please do the following things and let me know what would be the result
first put raise #tales.Inspect in your home method in your PagesController
second <%= raise tale.inspect%> in _tale.html.erb.
want to check weather value of tale is null or not.

Related

Why one method work perfectly for one action and do not work for another?

I'm newbee in rails, so could you explain why method survey_type works for this (attempts/new):
<h2 class="survey-title">
<%= #survey.name %>
<p><small><%= #attempt.survey.description %></small></p>
</h2>
<%= form_for(#attempt, url: attempt_scope(#attempt)) do |f| %>
<%= hidden_field_tag :survey_id, #survey.id %>
<ol class="questions">
<% if is_multanswer?(#survey.survey_type) %>
<%= f.fields_for :answers, get_answer_fields(#attempt) do |answer_fields| %>
<li>
<% question = answer_fields.object.question %>
<p class="question"><%= question.text %></p>
<ul class="options">
<%= collection_check_boxes('survey_attempt[answers_attributes]', question.id, question.options, :id, :text) do |b| %>
<li class="checkbox">
<%= b.label { b.check_box + b.text } %>
</li>
<% end %>
</ul>
</li>
<% end -%>
<% else %>
<%= f.fields_for :answers, get_answer_fields(#attempt) do |answer_fields| %>
<li>
<% question = answer_fields.object.question %>
<p class="question"><%= question.text %></p>
<ul class="options">
<%= collection_radio_buttons('survey_attempt[answers_attributes]', question.id, question.options, :id, :text) do |b| %>
<li class="radio">
<%= b.label { b.radio_button + b.text } %>
</li>
<% end %>
</ul>
</li>
<% end -%>
<% end %>
</ol>
<%= f.submit "Submit", class: 'btn btn-default' %>
<% end -%>
and do not work for this (attempts/show):
<div class="container">
<h2 class="survey-title">
<%= #attempt.survey.name %>
<p><small><%= #attempt.survey.description %></small></p>
</h2>
<ol class="questions">
<% if is_multanswer?(#survey.survey_type) %>
<% #attempt.answers.each do |answer| %>
<li>
<p class="question"> <%= answer.question.text %> </p>
<ul class="options">
<% answer.question.options.each do |option| %>
<li class="checkbox">
<label>
<%= check_box_tag '', '', the_chosen_one?(answer, option), disabled: true %>
<% color = get_color_of_option(answer, option) %>
<span class="<%= color %> <%= the_chosen_one?(answer, option) %>"> <%= option.text %> <%= get_weight(option) %> </span>
</label>
<p class="answers-number"> <%= number_of_people_who_also_answered(option.id) %> </p>
</li>
<% end %>
</ul>
</li>
<% end %>
<% else %>
<% #attempt.answers.each do |answer| %>
<li>
<p class="question"> <%= answer.question.text %> </p>
<ul class="options">
<% answer.question.options.each do |option| %>
<li class="radio">
<label>
<%= radio_button_tag '', '', the_chosen_one?(answer, option), disabled: true %>
<% color = get_color_of_option(answer, option) %>
<span class="<%= color %> <%= the_chosen_one?(answer, option) %>"> <%= option.text %> <%= get_weight(option) %> </span>
</label>
<p class="answers-number"> <%= number_of_people_who_also_answered(option.id) %> </p>
</li>
<% end %>
</ul>
</li>
<% end %>
<% end %>
here is controllers:
attempts_controller
class AttemptsController < ApplicationController
helper 'surveys'
before_filter :load_survey, only: [:new, :create]
def index
#surveys = Survey::Survey.active
end
def show
#attempt = Survey::Attempt.find_by(id: params[:id])
render :access_error if current_user.id != #attempt.participant_id
end
def new
#participant = current_user
unless #survey.nil?
#attempt = #survey.attempts.new
#attempt.answers.build
end
end
def create
#attempt = #survey.attempts.new(params_whitelist)
#attempt.participant = current_user
if #attempt.valid? && #attempt.save
correct_options_text = #survey.correct_options.present? ? 'Bellow are the correct answers marked in green' : ''
redirect_to attempt_path(#attempt.id), notice: "Thank you for answering #{#survey.name}! #{correct_options_text}"
else
build_flash(#attempt)
#participant = current_user
render :new
end
end
def delete_user_attempts
Survey::Attempt.where(participant_id: params[:user_id], survey_id: params[:survey_id]).destroy_all
redirect_to new_attempt_path(survey_id: params[:survey_id])
end
private
def load_survey
#survey = Survey::Survey.find_by(id: params[:survey_id])
end
def params_whitelist
if params[:survey_attempt]
params[:survey_attempt][:answers_attributes] = params[:survey_attempt][:answers_attributes].map { |attrs| { question_id: attrs.first, option_id: attrs.last } }
params.require(:survey_attempt).permit(Survey::Attempt::AccessibleAttributes)
end
end
def current_user
view_context.current_user
end
end
and surveys_controller:
class SurveysController < ApplicationController
before_filter :load_survey, only: [:show, :edit, :update, :destroy]
def index
type = view_context.get_survey_type(params[:type])
query = if type then Survey::Survey.where(survey_type: type) else Survey::Survey end
#surveys = query.order(created_at: :desc).page(params[:page]).per(15)
end
def new
#survey = Survey::Survey.new(survey_type: view_context.get_survey_type(params[:type]))
end
def create
#survey = Survey::Survey.new(params_whitelist)
if #survey.valid? && #survey.save
default_redirect
else
build_flash(#survey)
render :new
end
end
def edit
end
def show
end
def update
if #survey.update_attributes(params_whitelist)
default_redirect
else
build_flash(#survey)
render :edit
end
end
def destroy
#survey.destroy
default_redirect
end
private
def default_redirect
redirect_to surveys_path, notice: I18n.t("surveys_controller.#{action_name}")
end
def load_survey
#survey = Survey::Survey.find(params[:id])
end
def params_whitelist
params.require(:survey_survey).permit(Survey::Survey::AccessibleAttributes << :survey_type)
end
end
and helpers:
def get_color_of_option answer, option
if is_quiz?(answer.question.survey.survey_type)
if option.correct
'bg-success'
elsif the_chosen_one?(answer, option)
'bg-danger'
end
elsif is_score?(answer.question.survey.survey_type)
get_weight_html_class option
end
end
def get_survey_type survey_type
get_survey_types[survey_type] || get_survey_types.invert[survey_type]
end
def get_survey_types
{ 0 => 'quiz',
1 => 'score',
2 => 'poll',
3 => 'multanswer'
}
end
def is_quiz? something
something == 0 || something == 'quiz'
end
def is_score? something
something == 1 || something == 'score'
end
def is_poll? something
something == 2 || something == 'poll'
end
def is_multanswer? something
something == 3 || something == 'multanswer'
end
Thanks in advance!
In your AttemptsController you have
before_filter :load_survey, only: [:new, :create]
that sets the #survey variable for your new action, but doesn't get called for show, so that action never gets the variable set.
You can add :show into your :only conditions
before_filter :load_survey, only: [:new, :create, :show]
and that should fix things

rails application displaying blank space in users(venue) place

I am able to post an event but when I select the user to post as, the dropdown menu shows empty spaces where the user (venue name) should be. I have tried everything that I can think of. Any ideas would be greatly appreciated.
I am on rails 4. I am using devise as well.
here are my files:
show.html.erb:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #gig.user.venue_name %>
</p>
<p>
<strong>Event:</strong>
<%= #gig.event %>
</p>
<p>
<strong>Date:</strong>
<%= #gig.date %>
</p>
<p>
<strong>Doors:</strong>
<%= #gig.doors %>
</p>
<p>
<strong>Showtime:</strong>
<%= #gig.showtime %>
</p>
<p>
<strong>Age:</strong>
<%= #gig.age %>
</p>
<p>
<strong>Price:</strong>
<%= #gig.price %>
</p>
<p>
<strong>Description:</strong>
<%= #gig.description %>
</p>
<%= link_to 'Edit', edit_gig_path(#gig) %> |
<%= link_to 'Back', gigs_path %>
index.html.erb:
<p id="notice"><%= notice %></p>
<div class="page-header">
<h1>All Gigs</h1>
</div>
<% #gigs.each do |gig| %>
<div class="gig">
<strong><%= gig.user.venue_name %></strong>
<p><%= gig.event %></p>
<p><%= gig.date %></p>
<p><%= gig.doors %></p>
<p><%= gig.showtime %></p>
<p><%= gig.age %></p>
<p><%= gig.price %></p>
<p><%= gig.description %></p>
<div class="meta">
<%= link_to time_ago_in_words(gig.created_at) + " ago", gig %>
<span class="admin">
| <%= link_to 'Edit', edit_gig_path(gig) %> |
<%= link_to 'Delete', gig, method: :delete, data: { confirm: 'Are you sure?' } %>
</span>
</div>
</div>
<% end %>
</tbody>
</table>
gig.rb:
class Gig < ActiveRecord::Base
belongs_to :user
end
user.rb:
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 :gigs
end
_form.html.erb:
<%= simple_form_for(#gig, html: {class: "form-horizontal"}) do |f| %>
<% if #gig.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#gig.errors.count, "error") %> prohibited this gig from being saved:</h2>
<ul>
<% #gig.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.input :user_id, collection: User.all, label_method: :venue_name %>
<%= f.input :event %>
<%= f.input :date %>
<%= f.input :doors %>
<%= f.input :showtime %>
<%= f.input :age %>
<%= f.input :price %>
<%= f.input :description %>
<div class="form-actions">
<%= f.button :submit %>
</div>
db migrate add user id to gig
class AddUserIdToGigs < ActiveRecord::Migration
def change
add_column :gigs, :user_id, :integer
add_index :gigs, :user_id
remove_column :gigs, :name
end
end
gigs_controller.rb
class GigsController < ApplicationController
before_action :set_gig, only: [:show, :edit, :update, :destroy]
# GET /gigs
# GET /gigs.json
def index
#gigs = Gig.all
end
# GET /gigs/1
# GET /gigs/1.json
def show
end
# GET /gigs/new
def new
#gig = Gig.new
end
# GET /gigs/1/edit
def edit
end
# POST /gigs
# POST /gigs.json
def create
#gig = Gig.new(gig_params)
respond_to do |format|
if #gig.save
format.html { redirect_to #gig, notice: 'Gig was successfully created.' }
format.json { render :show, status: :created, location: #gig }
else
format.html { render :new }
format.json { render json: #gig.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gigs/1
# PATCH/PUT /gigs/1.json
def update
respond_to do |format|
if #gig.update(gig_params)
format.html { redirect_to #gig, notice: 'Gig was successfully updated.' }
format.json { render :show, status: :ok, location: #gig }
else
format.html { render :edit }
format.json { render json: #gig.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gigs/1
# DELETE /gigs/1.json
def destroy
#gig.destroy
respond_to do |format|
format.html { redirect_to gigs_url, notice: 'Gig was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gig
#gig = Gig.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gig_params
params.require(:gig).permit(:name, :event, :date, :doors, :showtime, :age, :price, :description, :user_id)
end
end
Solved it:
After running irb, I noticed that venues was null in the db. Therefore, I realized that I had to as venues in devise by creating new forms.

How to access hidden_field in controller in Ruby on rails

Question: How to access hidden field value post_id from file view/comments/_comment.html.erb and use it in controllers/dashboards_controller.rb?
- there are 2 controllers - dashboard and comments, and using gem act_as_commentable_with_threading
Now I get: ActiveRecord::RecordNotFound in DashboardsController#index Couldn't find Post without an ID
config/routes.rb
resources :comments, :only => [:create, :destroy]
controllers/dashboards_controller.rb
class DashboardsController < ApplicationController
def index
#post = Post.new
#user = current_user
#newest_users = User.newest_players
#feed_posts = Post.paginate(:page => params[:page], :per_page => 8)
#last_clubs = Club.last_clubs
#commented_post = Post.find(params[:post_id])
# trying to access params from view/comments/_comment.html.erb
# comments is another controller...
# do other operations with #commented_post
#comments = #commented_post.comment_threads.order('created_at desc')
#new_comment = Comment.build_from(#commented_post, current_user, '')
end
end
view/comments/_comment.html.erb
Add comment
place for a comment form
<div class="comment-form">
<%= form_for :comment, :remote => true do |f| %>
<%=f.hidden_field 'post_id', post.id %>
# need to use this value in dasboard controller
<%=f.text_field :body %>
<% end %>
</div>
view/dashboards/_feed_post.html.erb
<ul class="post-items">
<%if #feed_posts.any? %>
<% #feed_posts.each do |post| %>
<li>
<span class="image"><%= image_tag post.image.url(:message) if post.image?%></span>
<span class="content"><%= post.text_html %></span>
<span class="tags">Tags:<%= post.tag_list %></span>
<span class="meta">
Posted <%= time_ago_in_words(post.created_at) %> ago.
| <%= post.user.full_name %>
</span>
<%= render 'comments/form' ,:locals => { :comment => #new_comment, :post_id => post.id } %>
<%= render 'comments/comment', :collection => #comments, :as => :comment, :post_id => post.id %>
</li>
<% end %>
<% end %>
</ul>
view/dashboards/index
<div class="row">
<div class="span7">
<!--form for creating a new post-->
<section>
<%= render :template => 'posts/new' %>
</section>
<!--dashboard feed_post-->
<section>
<%= render :partial => 'dashboards/feed_post' %>
</section>
</div>
you are using f.hidden_field so you will get
<%=f.hidden_field 'post_id', post.id %>
will create following html ref hidden_field
<input type="hidden" id="comment_post_id" name="comment[post_id]" value="#{comment.post_id}" />
so you can access this as following in your controller
params[:comment][:post_id]
so use following instead
#commented_post = Post.find(params[:comment][:post_id])
if you want 'post_id' in params[:post_id] use hidden_field_tag like following
<%= hidden_field_tag 'post_id', post.id %>

Like button does not update with AJAX

I am passing a collection (#feed_items) to a _feed_item partial via the :collection option and converting it to dailypost with :as => :dailypost.
Inside the _feed_item partial I rendered another partial for _like_button, and i used :locals to continue using dailypost.
Everything works fine with the database. Likes get added and taken out :) BUT
I am trying to use (AJAX) to create.js.erb & destroy.js.erb the like button.
For some reason only the top post gets updated correctly and i have to refresh the page to see the ones below it.
I know the solution involves assigning a unique post id to each "like" element, say "like-123", but that is where i am stuck.......
I also know that the problem may be in _feed_items.html.erb because i am passing two ids....any suggestions??
Views
_feed.html.erb
<% if #feed_items.any? %>
<ol>
<%= render partial: 'shared/feed_item', collection: #feed_items, :as => :dailypost %>
</ol>
<% end %>
_feed_items.html.erb
<li id="<%= #dailypost.id %>">
<span class="user">
<%= link_to dailypost.user.name, dailypost.user %>
<span class="content"><%= dailypost.content_html %></span>
<div id="like">
<%= render :partial => 'likes/like_button', :locals =>{:dailypost => dailypost} %>
</div>
</li>
_like_button.html.erb
<% if like = current_user.likes.find_by_dailypost_id(dailypost.id) %>
<%= form_for like, :html => { :method => :delete }, :remote => true do |f| %>
<%= f.submit "Unlike" %>
<% end %>
<% else %>
<%= form_for current_user.likes.build, :remote => true do |f| %>
<div><%= f.hidden_field :dailypost_id, value: dailypost.id %></div>
<%= f.hidden_field :user_id %>
<%= f.submit "Like" %>
<% end %>
<% end %>
create.js.erb
$("#like").html("<%= escape_javascript(render :partial => 'like_button', :locals => {:dailypost => #dailypost}) %>");
destroy.js.erb
$("#like").html("<%= escape_javascript(render :partial => 'like_button', :locals => {:dailypost => #dailypost}) %>");
Controller
class LikesController < ApplicationController
respond_to :html, :js
def create
#like = Like.create(params[:like])
#dailypost = #like.dailypost
respond_to do |format|
format.js
format.html { redirect_to :back }
end
end
def destroy
like = Like.find(params[:id]).destroy
#dailypost = like.dailypost
respond_to do |format|
format.js
format.html { redirect_to :back }
end
end
end
Hmmm.Replace the first-line in _feed_items.html.erb with this.
<li id="dailypost<%= dailypost.id %>">
and In create.js.erb and destroy.js.erb, make changes
$("#like").html(...)
To
$("#dailypost<%= dailypost.id%> #like").html(...)
This should Work.

Ruby On Rails: Active Recode method Save is undefined when called in Link Controller,

I', working on a Ruby On Rails App, and I am getting the following error when I attempt to call the Save method from Active Record to populate a new link to the database. This is code that goes wrong, its in the Create method in my LinksController class:
def create
#link = Link.new(params[:link])
respond_to do |format|
if #product.save
format.html { render :action => "create" }
format.json { render :json => #link }
else
format.html { render :action => "new" }
format.json { render :json => #product.errors, :status => :unprocessable_entity }
end
end
end
When I go to
http://localhost:3000/links/new
And attempt to create a new link with this form:
<%= form_for(#link) do |f| %>
<% if #link.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#link.errors.count, "error") %> prohibited this link from being saved:</h2>
<ul>
<% #link.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div>
<div class="actions">
<%= f.submit %>
</div>
and click submit, I get the following error:
undefined method `save' for nil:NilClass
I have no idea what is going on, so if anyone has an answer, or even pointers, I would really appreciate it. Thanks.
#link = Link.new(params[:link])
respond_to do |format|
if #product.save
so where did #productcome from?

Resources