Simple Undefined Method Error - Rails - ruby-on-rails

I'm probably overlooking something simple here but I still haven't been able to find the problem.
Controller:
(First line is a long Thinking Sphinx query)
#artwork_q = Artwork.search params[:q], :conditions => {:subject => params[:artwork][:subject_ids], :location => params[:artwork][:location_ids], :artist_last => params[:artwork][:artist_id], :artist_first => params[:artwork][:artist_id]}, :order => params[:sort][:title]
#last_artwork = Artwork.new
#last_artwork = #artwork_q.last
render 'index2'
View:
<% #artwork_q.each.with_index do |art, index| %>
<div class="a-result<%= " last-one" if art.id == #last_artwork.id %>" id="<%= index %>">
<% end %>
I tested art.id and that's working fine. It's the #last_artwork.id that's raising the error which is this:
NoMethodError in Artworks#index2
Showing /Users/<user>/Developer/<project>/<rails_root>/app/views/artworks/index2.html.erb where line #49 raised:
undefined method `id' for nil:NilClass
Thank you for any help!

[].last => nil i.e. your query returns no results. Simply check #artwork_q has some results in before looping through them.
<% unless #artwork_q.blank? %>
<% #artwork_q.each.with_index do |art, index| %>
<div class="a-result<%= " last-one" if art.id == #last_artwork.id %>" id="<%= index %>">
<% end %>
<% end %>

Try this:
<% unless #artwork_q.blank? %>
<% #artwork_q.each.with_index do |art, index| %>
<% unless #last_artwork.blank? %>
<div class="a-result<%= " last-one" if art.id == #last_artwork.id %>" id="<%= index %>">
<% end %>
<% end %>
<% end %>

Related

Error with instance variable in Index view

So in my tutors_controller.rb this is my index action
def index
#tutor = Tutor.all
#tutor = #tutor.fees_search(params[:fees_search]) if params[:fees_search].present?
end
and in my index.html.erb this is the view
<div class='container'>
<%= form_tag(tutors_path, method: :get) do %>
<%= label_tag 'fees_search', 'Max Fees' %>
<%= select_tag 'fees_search', options_for_select((10..50).step(10)) %>
<%= submit_tag 'Filter' %>
<% end %>
<% #tutor.each do |tutor| %>
<% unless tutor.admin? %>
<div class='row' id='tutor-listing'>
<div class='col-xs-4'>
<%= image_tag(tutor.profile.avatar.url, :class => "img-rounded" ) if tutor.profile.avatar? %>
</div>
<div class='col-xs-8'>
<h3><%= link_to tutor.full_name, tutor_path(tutor) %></h3>
<% unless tutor.subjects.nil? %>
<% tutor.subjects.each do |subs| %>
<span class='badge'id='tutor-listing-badge'>
<%= link_to subs.name, subject_path(subs) %>
</span>
<% end %>
<% end %>
<% unless current_tutor %>
<%= button_to "Shortlist Tutor", add_to_cart_path(tutor.id), :method => :post %>
<% end %>
</div>
</div>
<% end %>
<% end %>
</div>
So i understand that when the index view first renders, #tutor would simply be Tutor.all so it renders each individual tutor perfectly.
After trying to filter it though, i start receiving errors. The exact error is NoMethodError in Tutors#indexand the highlighted line is <% unless tutor.admin? %>
profile.rb model
class Profile < ActiveRecord::Base
belongs_to :tutor
scope :fees_to, -> (fees_to) { where("fees_to <= ?", "#{fees_to}") }
end
tutor.rb model
class Tutor < ActiveRecord::Base
has_one :profile, dependent: :destroy
def self.fees_search(n)
#profile = Profile.fees_to(n)
if #profile.empty?
return Tutor.none
else
#profile.each do |y|
y.tutor
end
end
end
end
I get that now my #tutor instance variable has obviously changed. But how do i go about resolving this problem? Should i be rendering a partial instead? Obviously my index action in my controller could be "better" also but i'm quite confused now as to what i should be doing.
Would appreciate any advice! Thank you!
#profile.each do |y|
y.tutor
end
Seems to be a problem. All the other outcomes are a Tutor.something scope, whereas this will return the last tutor only. Change each to map to get an array of Tutors instead.

Spree commerce taxonomies error

undefined method `each' for nil:NilClass
<% max_level = Spree::Config[:max_level_in_taxons_menu] || 1 %>
<nav id="taxonomies" class="sidebar-item" data-hook>
<% #taxonomies.each do |taxonomy| %>
<% unless taxonomy.name == 'Tags' %>
<h6 class="taxonomy-root"><%= Spree.t(:shop_by_taxonomy, :taxonomy => taxonomy.name) %></h6>
<%= taxons_tree(taxonomy.root, #taxon, Spree::Config[:max_level_in_taxons_menu] || 1) %>
This is the error i am getting and this is the code i updated to taxonomies.each.to_a not sure if that is right and how do i update the code so the server will run the new code instead of the older code?
Here is the updated code
<% max_level = Spree::Config[:max_level_in_taxons_menu] || 1 %>
<nav id="taxonomies" class="sidebar-item" data-hook>
<% #taxonomies.each.to_a do |taxonomy| %>
<% cache [I18n.locale, taxonomy, max_level] do %>
<h6 class='taxonomy-root'><%= Spree.t(:shop_by_taxonomy, :taxonomy => taxonomy.name) %></h6>
<%= taxons_tree(taxonomy.root, #taxon, max_level) %>
<% end %>
<% end %>
</nav>
Looks like what you're doing is forcing a nil object to an array, which will work, yt isn't an ideal solution. You can wrap the whole thing in this:
<% if #taxonomies && #taxonomies.any? %>
#your code goes here
<% end %>
...which will check for the presence of a taxonomies variable and make sure it isn't an empty array before running your code. As far as getting the code on the server goes, you'll have to post more info about your deployment setup and version control to answer that question.

Display products from ShopSense API

How do I display products from the ShopSense API in Rails using shopsense-ruby?
JSON.parse(response)["products"] is returning nil:
NoMethodError in Main#index
Showing /home/dev/demo-shopsense/app/views/shared/_shopsense.html.erb where line #3 raised:
undefined method `any?' for nil:NilClass
Extracted source (around line #2):
<div class="custom_widget">
<% if #products.any %>
<% #products.each do |product| %>
<div class="product">
<%= image_tag product['image']['url'] %>
<p><%= product['name'] %></p>
main_controller.rb:
class MainController < ApplicationController
def index
client = Shopsense::API.new('partner_id' => 'uid0000-0000000-00')
response = client.get_looks("New")
#products = JSON.parse(response)["products"]
end
end
shared/_shopsense.html.erb:
<div class="custom_widget">
<% if #products.any? %>
<% #products.each do |product| %>
<div class="product">
<%= image_tag product['image']['url'] %>
<p><%= product['name'] %></p>
</div>
<% end %>
<% end %>
</div>
I've set up a simple demo app demo-shopsense that should be easy to get up and running.
The parsed response of your request looks like this:
{"totalCount"=>"536121",
"looks"=>
[{"id"=>"12328367",
"title"=>"black",
...
As you can see instead of 'products' we have 'looks'.
#products = JSON.parse(response)["looks"]
When you are working with external services, it's very important to find out the exact format of the response.
EDIT:
I think in this case you actually need to use 'search' method on the client instead of 'get_looks', if you want to get products.

Rails erb formatting troubles, phantom spaces

Halp! My template is formatting strangely and I can't fathom how/why.
<% #poll.questions_all.each do |q| %>
<td>
<span class="optionvalue">
<% if can? :read_full, #poll %>
<%= resp[:texts][q.id] %>
<% else %>
<%= resp[:texts][q.id].nil? ? '' : resp[:texts][q.id].gsub(Question::POISON_WORDS_REGEX, '---') %>
<% end %>
</span>
<% unless q.options.empty? %>
<%= q.get_matching_option(resp[:texts][q.id])? ": #{q.get_matching_option(resp[:texts][q.id])}" : '' %>
<% end %>
</td>
<% end %>
Results in this:
A : Playgrounds
No idea where that first space is coming form, and every effort to get rid of it has failed! The generated markup:
<td>
<span class="optionvalue">
A
</span>
: Playgrounds
</td>
Try using the <%- -%> version of erb tags, these should suppress the extra whitespaces:
<%- if can? :read_full, #poll -%>
<%= resp[:texts][q.id] %>
<%- else -%>
<%= resp[:texts][q.id].nil? ? '' : resp[:texts][q.id].gsub(Question::POISON_WORDS_REGEX, '---') %>
<%- end -%>
I don't recall if you need them in both the opening and ending tags, but I'd suggest playing around with it and see if you can get what you want.
Horrible solution, but it works:
<% #poll.questions_all.each do |q| %>
<td>
<span class="optionvalue">
<% if can? :read_full, #poll %>
<%= resp[:texts][q.id] %></span><%= q.get_matching_option(resp[:texts][q.id])? ": #{q.get_matching_option(resp[:texts][q.id])}" : '' unless q.options.empty? %>
<% else %>
<%= resp[:texts][q.id].nil? ? '' : resp[:texts][q.id].gsub(Question::POISON_WORDS_REGEX, '---') %></span><%= q.get_matching_option(resp[:texts][q.id])? ": #{q.get_matching_option(resp[:texts][q.id])}" : '' unless q.options.empty? %>
<% end %>
</td>
<% end %>
I am pretty sure erb will do the right thing (not add unwanted lines) if you keep everything on one line of HTML.
For this case, and in general, I recommend that you put any logic for generating the content in methods in the view helper file (or if you're feeling lazy, in a code block in the erb, as in this example):
<% #poll.questions_all.each do |q| %>
<%
if can? :read_full, #poll
texts = resp[:texts][q.id]
else
texts = (resp[:texts][q.id].nil? ? '' : resp[:texts][q.id].gsub(Question::POISON_WORDS_REGEX, '---'))
end
if q.options.empty?
matching_options = ''
else
matching_options = (q.get_matching_option(resp[:texts][q.id])? ": #{q.get_matching_option(resp[:texts][q.id])}" : '')
end
%>
<td>
<span class="optionvalue"><%= texts %></span><%= matching_options %>
</td>
<% end %>

kaminari and order_by

So Im listing out all the members of my site and grouping them by name so that the list will be organized better. So in my view all my members are grouped by the first letter of their member name like:
B
Bakedfish
Beercan Dan
Bigmike33x
C
Cynicalassassin
ect..
Anyway, I also want to paginate this list but I cant add Kaminari's pagination arguments to my controller if Im using order because I get an undefined method error.
so this doesnt work:
#members = Member.all.group_by{|u| u.fullname[0].titleize}.page(params[:page]).per(18)
my view looks like this:
<div class="content">
<%= paginate #members %>
</div>
<% #members.keys.sort.each do |starting_letter| %>
<h3>
<%= link_to starting_letter, {:action => :browse, :controller =>:members, :letter => starting_letter } %>
</h3>
<ol>
<% #members[starting_letter].each do |member| %>
<li>
<% if member.is_artist? %>
<%= link_to member.full_name, member_path(member), :class=>"artist" %>
<% else %>
<%= link_to member.full_name, member_path(member) %>
<% end %>
</li>
<% end %>
</ol>
<% end %>
Here is my error message:
NoMethodError (undefined method `page' for #<Hash:0x007f78d4bf48f8>):
app/controllers/members_controller.rb:10:in `index'
Kaminari adds page method to ActiveRecord::Relation but Member.all.group_by returns hash. That is why you get this exception.
I'd suggest to perform grouping after pagination, e.g.:
#members = Member.order(:full_name).page(params[:page]).per(18).to_a.group_by { |u| u.fullname[0].upcase }
UPDATE
In order to use paginate helper you could assign 2 variables, e.g.:
#paginated_members = Member.order(:full_name).page(params[:page]).per(18)
#members = #paginated_members.to_a.group_by { |u| u.fullname[0].upcase }
And pass #paginated_members to the paginate helper.

Resources