I am trying to list the product reviews in spree back end. But getting the error 'undefined method any '. I am new to ruby,please help me to solve this issue.
Thanks in Advance.
Index.html.erb:
<% if #reviews.any? %>
<table class="index">
<colgroup>
<col style="width: 25%;">
<col style="width: 10%;">
<col style="width: 10%;">
<col style="width: 20%;">
<col style="width: 15%;">
<col style="width: 17%;">
</colgroup>
<thead>
<tr>
<th><%= Spree.t('product') %></th>
<th><%= Spree::Review.human_attribute_name(:rating) %></th>
<th><%= Spree.t('feedback') %></th>
<th><%= Spree::Review.human_attribute_name(:user) %></th>
<th><%= Spree::Review.human_attribute_name(:created_at) %></th>
</tr>
</thead>
<tbody>
<%- #reviews.each do |review| -%>
<tr id="<%= dom_id review %>">
<td>
<% if review.product %>
<%= link_to review.product.name, product_path(review.product) %>
<% end %>
</td>
<td class="align-center">
<%= txt_stars(review.rating) %>
</td>
<td class="align-center">
<%= link_to "(#{review.feedback_stars}/#{review.feedback_reviews.size})", admin_review_feedback_reviews_path(review) %>
</td>
<td class="align-center">
<%= review.user_id ? link_to(review.user.try(:email), [:admin, review.user]) : Spree.t(:anonymous) %></p>
<p><%= Spree::Review.human_attribute_name(:ip_address) %>: <%= review.ip_address ? link_to(review.ip_address, "http://whois.domaintools.com/#{review.ip_address}") : '-' %></p>
</td>
<td class="align-center">
<%= l review.created_at, :format => :short %>
</td>
<td class="actions">
<%= link_to_with_icon 'check', Spree.t('approve'), approve_admin_review_url(review), :no_text => true, class: 'approve' unless review.approved %>
<%= link_to_edit review, :no_text => true, :class => 'edit' %>
<%= link_to_delete review, :no_text => true %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<div class="no-objects-found">
<%= Spree.t(:no_results) %>
</div>
<% end %>
The above shown is the index.html.erb file , where the listing and ransack search is done.
Model File : review.rb
class Spree::Review < ActiveRecord::Base
belongs_to :product, touch: true
belongs_to :user, :class_name => Spree.user_class.to_s
has_many :feedback_reviews
after_save :recalculate_product_rating, :if => :approved?
after_destroy :recalculate_product_rating
validates :name, presence: true
validates :review, presence: true
validates :rating, numericality: { only_integer: true,
greater_than_or_equal_to: 1,
less_than_or_equal_to: 5,
message: Spree.t('you_must_enter_value_for_rating') }
default_scope { order("spree_reviews.created_at DESC") }
scope :localized, ->(lc) { where('spree_reviews.locale = ?', lc) }
scope :most_recent_first, -> { order('spree_reviews.created_at DESC') }
scope :oldest_first, -> { reorder('spree_reviews.created_at ASC') }
scope :preview, -> { limit(Spree::Reviews::Config[:preview_size]).oldest_first }
scope :approved, -> { where(approved: true) }
scope :not_approved, -> { where(approved: false) }
scope :default_approval_filter, -> { Spree::Reviews::Config[:include_unapproved_reviews] ? all : approved }
def feedback_stars
return 0 if feedback_reviews.size <= 0
((feedback_reviews.sum(:rating) / feedback_reviews.size) + 0.5).floor
end
def set_search
#search=Product.search(params[:q])
end
def recalculate_product_rating
self.product.recalculate_rating if product.present?
end
end
reviews_controller.rb
class Spree::Admin::ReviewsController < Spree::Admin::ResourceController
helper Spree::ReviewsHelper
def index
#reviews = collection
end
def approve
r = Spree::Review.find(params[:id])
if r.update_attribute(:approved, true)
flash[:notice] = Spree.t("info_approve_review")
else
flash[:error] = Spree.t("error_approve_review")
end
redirect_to admin_reviews_path
end
def edit
if #review.product.nil?
flash[:error] = Spree.t("error_no_product")
redirect_to admin_reviews_path and return
end
end
private
def collection
params[:q] ||= {}
#search = Spree::Review.ransack(params[:q])
#collection = #search.result.includes([:product, :user, :feedback_reviews]).page(params[:page]).per(params[:per_page])
end
end
It looks like the important code is in your comment on an answer, where it is very difficult to read.
I think you have assigned the variable collection with an integer id, and assigned the result if the database lookup to #collection (which is a different variable)
So to fix it you could change the index action to
#reviews = #collection
any works with array on and your #reviews are not an array. Please check #reviews object. It should be array.
Related
I've got two basic Models:
- Account [id, name]
- Balance [id, account_id, date, balance]
Their controllers contain the default code from scaffolding plus I've modified the balances controller with a 'statement' function. This allows me to calculate the total balances of all the accounts at the most recent date stored in the balances table.
This is currently fine and working as expected, and my statement view displays the data.
However, how can I display a drop down list of all the 'dates' from the 'balances' table. And then set the #latestDate in the balances_controller.rb to the selected date in the drop down list.
I've tried adding this in statement.html.erb:
<%= form_for(#balance) do |b| %>
<%= b.label :date %><br>
<%= b.collection_select(:date, #dates, :id, :date) %>
<% end %>
However, I'm not sure if this is the correct approach and this throws the following error:
Couldn't find Balance with 'id'=
MY CODE:
account.rb
class Account < ActiveRecord::Base
has_many :balances
validates :name, presence: true, length: { maximum: 250 },
uniqueness: { case_sensitive: false }
end
balance.rb
class Balance < ActiveRecord::Base
belongs_to :account
validates :account, presence: true, length: { maximum: 250 }
end
balances_controller.rb
def index
#balances = Balance.all.order(date: :desc)
end
def new
#balance = Balance.new
end
def statement
#dates = Balance.all.order('date desc').dates
#latestDate = Balance.order('date desc').first.date
#summaryBalances = Balance.joins(:account).order('accounts.credit').where('date = :abc', {abc: #latestDate})
#assetTotal = Balance.joins(:account).where('date = :abc', {abc: #latestDate}).where("credit = 'f'").sum(:balance)
#creditTotal = Balance.joins(:account).where('date = :abc', {abc: #latestDate}).where("credit = 't'").sum(:balance)
#worth = #assetTotal - #creditTotal
end
balances/statement.html.erb
<h1>Statement at <%= #latestDate %></h1>
<p>(showing all balances from the (select top 1 date from balances))</p>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Account</th>
<th>Balance</th>
<th colspan="1"></th>
</tr>
</thead>
<tbody>
<% #summaryBalances.each do |balance| %>
<tr>
<% if !(balance.account.credit) %>
<td><%= balance.account.name %></td>
<% else %>
<td><%= balance.account.name + ' (Credit)' %></td>
<% end %>
<td class='account-balance'><%= number_to_currency(balance.balance, unit: "£") %></td>
<td><%= link_to 'Edit', edit_balance_path(balance) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
<h5>Assets:</h5>
<%= number_to_currency(#assetTotal, unit: "£") %>
<h5>Liabilities:</h5>
<%= number_to_currency(#creditTotal, unit: "£") %>
<h5>Net Worth:</h5>
<%= number_to_currency(#worth, unit: "£") %>
Based on your comments, simply add :statement to that before_action as follows:
before_action :set_balance, only: [:show, :edit, :update, :destroy, :statement]
Since you reference #balances from the form as well, you'll need to set this within the statement action on the controller.
def statement
#balances = Balance.all # Or whichever balances you want
# Your existing code here...
end
I have two models Employee and Overtime Definition The Associations are set like this
Employee
class Employee < ActiveRecord::Base
has_many :overtime_definitions
Overtime Definition
class OvertimeDefinition < ActiveRecord::Base
belongs_to :employee
I created an Overtime definition for an employee and it all looks fine.However I'm having trouble with editing the same for an employee.
overtime_definitions__controller:
def new
#flag = params[:flag]
#employee = Employee.find(params[:id])
#overtime = OvertimeDefinition.new
end
def create
#employee = Employee.find(params[:overtime_definition][:employee_id])
#overtime = OvertimeDefinition.new(params[:overtime_definition])
if (params[:half_day_extra_duty_hours][:hour].to_s !="" || params[:half_day_extra_duty_hours][:minute].to_s !="")
#overtime.half_day_extra_duty_hours = params[:half_day_extra_duty_hours][:hour].to_s + ":" + params[:half_day_extra_duty_hours][:minute].to_s + ":" + "00"
else
#overtime.half_day_extra_duty_hours = nil
end
if (params[:full_day_extra_duty_hours][:hour].to_s !="" || params[:full_day_extra_duty_hours][:minute].to_s !="")
#overtime.full_day_extra_duty_hours = params[:full_day_extra_duty_hours][:hour].to_s + ":" + params[:full_day_extra_duty_hours][:minute].to_s + ":" + "00"
else
#overtime.full_day_extra_duty_hours = nil
end
if #overtime.save
flash[:notice] = "Overtime Successfully Created for #{#employee.name}"
redirect_to :action => 'search_overtime'
end
end
def edit
#flag = params[:flag]
#overtime = OvertimeDefinition.find(params[:id][:employee_id])
#employee = Employee.find(params[:id])
end
def update
#employee = Employee.find(params[:id])
#overtime = OvertimeDefinition.find(params[:id])
if #overtime.update_attributes(params[:overtime_definition])
flash[:notice] = "Overtime Successfully Updated for #{#employee.name}"
redirect_to :action => 'search_overtime'
else
render :action => 'edit',:flag=>params[:flag]
end
end
Tried with these in the edit method
#overtime = OvertimeDefinition.find(params[:id][:employee_id])
#gives me can't convert Symbol into Integer error.
#overtime = OvertimeDefinition.find(params[:id])
#gives me Couldn't find OvertimeDefinition with ID=1353 error.Actually 1353 is the id of that employee.
3.#overtime = OvertimeDefinition.find(params[:employee_id])
#gives me couldn't find OvertimeDefinition without an ID error.
My _search_overtime_employee_list having these links for new and edit actions
<%=link_to "Calculation" ,:action => "new",:id=>employee.id, :flag=>"Calculation" %>
<%= link_to "Re-Calculate",:action => "edit",:id=>employee.id,:flag=>"Re-Calculate" %>
new.rhtml
<%= form_tag :action => 'create' do %>
<%= render :partial =>'form'%>
<center>
<%= submit_tag "Save",:onclick=>"return validate()",:class=>"buttons"%>
</center>
<% end %>
<%= link_to "Back" ,:action => "search_overtime" %>
edit.rhtml
<%= form_tag :action => 'update', :id=>#employee.id,:flag=> params[:flag],:value=>params[:id] %>
<%= render :partial =>'form'%>
<center>
<%= submit_tag "Update",:onclick=>"return validate()",:class=>"buttons"%>
</center>
<%= link_to "Back" ,:action => "search_overtime" %>
_form.rhtml
Employee Details
<table cellspacing="5">
<tr>
<td><b>Employee Code</b></td>
<%= hidden_field 'overtime_definition','employee_id',:value=>params[:id] %>
<td><%= #employee.employeeid %></td>
<td><b>Employee Name</b></td>
<td><%= #employee.personnel.display_full_name %></td>
</tr>
<tr>
<td><b>Department</b></td>
<td><%= #employee.department ? #employee.department.name : "" %></td>
<td><b>Designation</b></td>
<td><%= #employee.designation ? #employee.designation.name : "" %></td>
<td><b>Location</b></td>
<td><%= #employee.location.name%></td>
</tr>
</table>
</br>
<fieldset>
<table cellspacing="5">
<%= form_for :overtime_definition, :builder => LabelFormBuilder do |od| %>
<tr>
<td>
<label for="half_day_extra_duty_hours">
Half Day Extra Duty Hours
</label>
</td>
<td class ="datefamily">
<%= select_time(#overtime.half_day_extra_duty_hours, {:include_blank => true, :time_separator => ":",:prefix => "half_day_extra_duty_hours"})%>
</td>
</tr>
<tr>
<td>
<label for="full_day_extra_duty_hours">
Full Day Extra Duty Hours
</label>
</td>
<td class ="datefamily">
<%= select_time(#overtime.full_day_extra_duty_hours, {:include_blank => true, :time_separator => ":",:prefix => "full_day_extra_duty_hours"})%>
</td>
</tr>
<tr>
<%= od.sr_check_box :is_salary_basis, {}, true, false, :label => "Is Salary Basis"%>
</tr>
<tr>
<%= od.sr_check_box :is_fixed_amount, {}, true, false, :label => "Is Fixed Amount"%>
<td colspan="2" id="ov_hm" style="display: none">
Half Day Amount
<%= od.text_field :half_day_amount, :onkeypress => "return numbersonly(event)", :style => "width:40px" %>
</td>
<td colspan="2" id="ov_fm" style="display: none">
Full Day Amount
<%= od.text_field :full_day_amount, :onkeypress => "return numbersonly(event)", :style => "width:40px" %>
</td>
</tr>
<%end%>
</table>
I just lost out here completely in getting that edit action work.Any help is greatly appreciated!
Your current edit link is:
<%= link_to "Re-Calculate",:action => "edit",:id=>employee.id,:flag=>"Re-Calculate" %>
In your edit action:
#overtime = OvertimeDefinition.find(params[:id][:employee_id]) ## gives me can't convert Symbol into Integer error.
As per the edit link, you are directly passing :id in query params which you can access as params[:id]. There is no params[:id][:employee_id] in your params hash so when you say params[:id][:employee_id] Ruby tries to convert :employee_id to an integer which is a symbol. Hence, the error.
I think you should be passing id of OvertimeDefinition record in :id from your link. And access it as
#overtime = OvertimeDefinition.find(params[:id])
in the Controller's action.
#overtime = OvertimeDefinition.find(params[:id]) ## gives me Couldn't
find OvertimeDefinition with ID=1353 error.Actually 1353 is the id of
that employee.
This is because you are passing employee id in params[:id] so obviously this will not work. You need to pass OvertimeDefinition id here.
#overtime = OvertimeDefinition.find(params[:employee_id]) ## gives me
couldn't find OvertimeDefinition without an ID error.
You are not passing any :employee_id in query params within edit link. So, params[:employee_id] will be nil and find method fails because you didn't pass any id to it.
Solution :
Update your edit link as below:
<%= link_to "Re-Calculate",:action => "edit",:id=> #overtimedefinition.id , :employee_id => employee.id,:flag=>"Re-Calculate" %>
Replace #overtimedefinition.id with appropriate id of OvertimeDefinition record. As you have not shared the code, I don't know the name of OvertimeDefinition variable.
Update your edit action as:
def edit
#flag = params[:flag]
#overtime = OvertimeDefinition.find(params[:id])
#employee = Employee.find(params[:employee_id])
end
In my application, there are two classes , which have 'has_many' relationship.
And from that design, I can fetch object from my controller(*_controler.rb) and can pass successfully to my view (*.html.erb)
But on view part(*.html.erb) i can not access object's collection class...
I got following exception:
ActionView::TemplateError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.inject) on line #31 of app/views/student/_populate.html.erb:
Model Classes:
class Student < ActiveRecord::Base
has_many :Subject, :class_name=>"Subject"
attr_accessible :first_name, :middle_name, :last_name,
self.table_name="students"
set_primary_key :id
blahblah
end
class Subject < ActiveRecord::Base
belongs_to :Student, :foreign_key=>'student_id'
attr_accessible :student_id, :name
self.table_name="subjects"
blahblah
end
Controller:
class StudentController < ApplicationController
require "student.rb"
def populate
#pos=0
filter_query = ''
if !params[:firstName].blank?
filter_query +=" first_name='" + params[:firstName].to_s + "' and"
end
if filter_query !=''
filter_query= filter_query[0..filter_query.length-4]
#stuData= Student.find(:all, :conditions=>filter_query)
end
end
View:
populate.html.erb
<div class="header">
<div class="heading" style="float:left;width:900px;">
<% form_tag(:controller=>"student", :action=>"populate") do %>
<table>
<tr>
<td width="10"> <label> First Name:</label> </td>
<td width="40"> <%= text_field_tag('firstName') %> </td>
</tr>
</table>
<input name="submitFormName" class="form_submit" type="submit" value="Search" />
<% end %>
<div height="10"> </div>
</div>
</div>
<div class="students" style="float:left;width:1330px;">
<% if !#stuData.blank? %>
size = <%= #stuData.size %>
<% if !#stuData.nil? %>
<%= render :partial=>'populate' , :locals=>{:stuData => #stuData} %>
<% end %>
<% else %>
<div>Not found...</div>
<% end %>
</div>
_populate.html.erb
<div style="overflow-y:auto;overflow-x:scroll;">
<table >
<thead>
<th>Id</th>
<th>First Name</th>
<th>Middle Name </th>
<th>Last Name</th>
<th>Subject Name</th>
</thead>
<% stuData.each do |item| %>
<tr>
<td id="studentId"> <%= item.id %> </td>
<td id="firstNameId"> <%= item.promotion_code %> </td>
<td id="middleNameId"> </td>
<td id="lastNameId"> </td>
<td id="cityId">
<% #var1 = item.Subject %>
<% if #var1.nil? %>
<% #var1.each do |pc| %>
<%= pc.name %>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</table>
</div>
I have crossed check on console:
#student = Student.find(144)
=> #<Student id: 4, first_name: "ABC", middle_name: "DEF", last_name: "GHI">
>>
?> #isNullCheck = #student.Subject.nil?
=> false
>>
?> #subList = #student.Subject
=> [#<Subject id: 5, student_id: 4, name: "Maths">, #<Subject id: 6, student_id: 4, name: "English"> ]
>>
?> #StuSub1 = #student.Subject[0]
=> #<Subject id: 5, student_id: 4, name: "Maths">
>>
?> #StuSub2 = #student.Subject[1]
=> #<Subject id: 6, student_id: 4, name: "English">
==
?> #StuSub3 = #student.Subject[2]
=> nil
>>
>> #StuSubValue1 = #student.Subject[0].value
=> Maths
>>
>> #StuSubValue2 = #student.Subject[0].value
=> English
>>
Problem:
When i will search any student details from the page(populate.html.erb), my controller will fetch the data and passed the object (#stuData) to the template(_populate.html.erb).
Template(_populate.html.erb) can print student's data.
But can not print student's subject's name. (As student has many subjects)
I have googled many things....
i think there is nothing wrong in model's design and controller part....
but i think problem might be with
page rendering or
local parameters passing to template or
collection parameter passing to template...
but i am not sure....
can any one help me in this???
Thanks in advance,
Your relationships are set up incorrectly. Variable names cannot begin with a capital letter. This article may help.
Set them up without using capitals and use plurals instead - like so:
has_many :subjects and belongs_to :student
and make sure you propagate changes through your views
I am trying to use will_paginate for a list of items I want to display.
There is a form with drop down selections to fetch objects by status.
This is my controller
def list
#person = Person.find_by_id(session[:person_id])
params[:status] = params[:redirect_status] if params.has_key?('redirect_status')
#statuses = Peptide.statuses
#status = 'Not Ordered'
#status = params[:status] if params[:status] != nil || params[:status] == ''
#peptides = Peptide.find(:all, :conditions => ['status = ?', #status]).paginate(:per_page => 30, :page => params[:page])
if Peptide.count.zero?
flash[:notice] = "There are not any peptides entered"
redirect_to :action => 'new'
end#if zero
end
This is in the view
<form action="/peptide/create_spreadsheet_of_not_ordered" enctype="multipart/form-data" method="post">
<table class="sortable" cellpading="5" cellspacing="2" width="100">
<tr class= "header-line">
<th>SS</th>
<th>Status</th>
<th>Peptide</th>
<th>Gene</th>
<th>Submitter</th>
<th>Created</th>
<th>Updated</th>
<th>Sequence</th>
<th>Modification</th>
<th>Vendor</th>
</tr>
<% for #peptide in #peptides.reverse %>
<tr valign = "top" class= "<%= cycle('color_one', 'color_two') %>">
<!--an error here during development likely indicates that the people table has not be repopulated or
that no submitter primer is present for a primer-->
<td sorttable_customkey = 0 > <%=check_box_tag "box[]", #peptide.id %>
<td><%= #peptide.status%></td>
<td class><%= link_to #peptide.name, :action => :report, :id => #peptide.id %></td>
<td><%= gene_links(#peptide.genes) rescue 'Error'%></td>
<td><%= #peptide.submitter.name rescue "" %></td>
<td <%= sorttable_customkey_from_date(#peptide.created_at)%> >
<%= #peptide.created_at.strftime("%b %d %Y") rescue "Unknown"%>
</td>
<td <%= sorttable_customkey_from_date(#peptide.updated_at)%> >
<%= #peptide.updated_at.strftime("%b %d %Y") rescue "Unknown"%>
</td>
<td><%= #peptide.sequence%></td>
<td><%= #peptide.modifications%></td>
<td><%= #peptide.vendor%></td>
<%= buttons() %>
</tr>
<%end%>
<%= will_paginate #peptides %>
</table>
<br>
<%= submit_tag "Create Spreadsheet"%>
The default list is grouped by status ordered.
however when I select any other status and submit the form the pagination links take me back to the default status.
Please help me resolve this issue.
Thanks
Without seeing the view, it sounds like you need to add the current params as an argument to the links for the other statuses...
Update
Try adding the params to your status link:
<%= link_to #peptide.name, peptide_path(#peptide, params), :action => :report, :id => #peptide.id %>
The documentation is here.
I'm very new to rails and have this fairly basic question:
I have a form that takes in an array:
<td><%= fields_for "days" do |form| %>
M: <%= form.check_box "", {}, 'M', '' %>
T: <%= form.check_box "", {}, 'T', '' %>
W: <%= form.check_box "", {}, 'W', '' %>
Th: <%= form.check_box "", {}, 'Th', '' %>
F: <%= form.check_box "", {}, 'F', '' %>
<% end %>
This should be accessible through params[:days]. How can I assign params[:days] to a variable within the controller? #days is not correct here, right? (There's no Days object, so there's no instance of that object). What should go in the [correct_variable] slot below?
[correct_variable] = params[:days]
Thanks!
In response to comments:
I tried using #days, but for some reason it wouldn't get called where I'd like it to. In particular, I'd like to pass it to my Search model:
class Search < ActiveRecord::Base
attr_accessible :name, :day, :units, :instructor
def courses
#courses ||= find_courses
end
private
def find_courses
Course.find(:all, :conditions => conditions)
end
def day_conditions
["courses.day LIKE ?", "%"+ #days.join("%")+"%"]
end
I first instantiate #days in my courses controller (which is connected, through the index method, to a partial that uses an instance of the Search object.
More code:
From courses/index.html.erb:
<% if #search.save %>
<div id = "results_scroll">
<%= render :partial => 'searches/search_results' %>
</div>
<% else %>
From search_results partial:
<% "Search" %>
<table>
<tr>
<th align="left" width="25%"><%= 'Name' %></th>
<th align="left" width="10%"><%= 'Number' %></th>
<th align="left" width="20%"><%= 'Instructor' %></th>
<th align="left" width="10%"><%= 'Room' %></th>
<th align="left" width="5%"><%= 'Day' %></th>
<th align="left" width="5%"><%= 'Units' %></th>
<th align="left" width="15%"><%= 'Time' %></th>
<th align="left" width="10%"><%= 'Limitations' %></th>
</tr>
<%= render :partial => #search_show.courses %>
</table>
From the courses controller (this has the #search_show variable).
def index
#courses = Course.order(sort_column + " " + sort_direction)
#search = Search.new
#search_show = Search.last
#title = "List"
#days = params[:days]
Finally, the _course.html.erb partial:
<tr>
<td><%= course.name %></td>
<td><%= course.number %></td>
<td><%= course.instructor %></td>
<td><%= course.room %></td>
<td><%= course.day %></td>
<td><%= course.units %></td>
<td><%= course.time %></td>
<td><%= course.limitations %></td>
<td><%= link_to 'Show', course %></td>
</tr>
This is not really an answer, but there is some problems with how you are trying to access your #days variable you set in the controller.
# your controller
...
def index
...
#days = params[:days]
# your model
...
private
def day_conditions
["courses.day LIKE ?", "%"+ #days.join("%")+"%"]
end
The #days, in your model, you are calling is not going to access the #days in your controller. Each #days belongs to their respective instances.
You should find a method of sending the #days from your controller into your models, instead of using global variables.
Solved the problem by using a $days global variable instead of #days.