Name Error - uninitialized constant Rails - ruby-on-rails

I'm adding search functionality to my ruby on rails app. Based on the Ryan Bates tutorial #111.
For some reason, my render call in my show page is resulting in
Name Error
uninitialized constant Search::Properties
My controller is simple
class SearchesController < ApplicationController
def new
#search = Search.new
end
def create
#search = Search.create(search_params)
redirect_to #search
end
def show
#search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit(:keywords, :category, :min_price, :max_price, :bedrooms, :bathrooms, :garage)
end
end
And I created a new class in my model
class Search < ActiveRecord::Base
def properties
properties = Properties.all
properties = properties.order(:title)
properties = properties.where(["title LIKE ?","%#{keywords}%"]) if keywords.present?
properties = properties.where([category: category]) if category.present?
properties = properties.where(["price >= ?","%#{min_price}%"]) if min_price.present?
properties = properties.where(["price <= ?","%#{max_price}%"]) if max_price.present?
properties = properties.where(["bedrooms == ?","%#{bedrooms}%"]) if bedrooms.present?
properties = properties.where(["bathrooms == ?","%#{bathrooms}%"]) if bathrooms.present?
properties = properties.where(["garage == ?","%#{garage}%"]) if garage.present?
properties
end
end
And my view
<div class="row property-list-wrapper">
<div class="container">
<div class="col-md-8 property-list-left">
<h1>We've found <%= pluralize(#properties.count, 'property')%> </h1>
<%= render #properties %>
</div>
<div class="col-md-4 property-list-right">
</div>
</div>
</div>
It seems that my render tag is not finding the class in my model. Am I missing something in my controller maybe?
I'm using rails 4.2.7 and ruby 2.2.4p230

Related

Action Listener on ruby on rails?

I have this project: https://todo-app-back-end-prospeed.c9users.io/
It's basically a reminder web app. I trying to add a function in which the user clicks on the checkbox and the value <Todo id: 24, description: "Publish project", pomodoro_estimate: 1, complete: nil the complete: nill changes to complete: true or false `
<body>
<div class="container2">
<h1 id ="list">Workshop Todo List</h1>
<ul>
<% #todos.each do |todo| %>
<li>
<label class="container">
<input type="checkbox"/ checked="checked">
<%= todo.description %>
<span class="pomodoro-estimate"><%= todo.pomodoro_estimate %> pomodoro</span>
<span class="checkmark"></span>
</label>
</li>
<% end %>
</ul>
<a class="noColor" href="/new/"><input class="add-new-todo-button" type="submit" value="Add todo"/></a>
<h1 id="Pomodoro-technique">What is a pomodoro estimate?</h1>
<p id="Pomodoro-technique-info">
<strong>1 pomodoro = 25 minutes + 5 minutes break.</strong><br>
For more info: https://www.focusboosterapp.com/the-pomodoro-technique
</p>
</div>
</body>
ToDoController:
class TodoController < ApplicationController
def index
#todos = Todo.all
end
def show
# Gets number user typed in URL
todo_id = params[:id]
#Grab the todo with that id from the database
#todo = Todo.find_by_id(todo_id)
end
def new
#
end
def create
t = Todo.new
t.description = params['description']
t.pomodoro_estimate = params['pomodoro_estimate']
t.save
redirect_to "/show/#{t.id}"
end
def destroy
t = Todo.find_by_id(params[:id])
t.destroy
redirect_to "/"
end
def edit
#todo = Todo.find_by_id(params[:id])
end
def update
t = Todo.find_by_id(params['id'])
t.description = params['description']
t.pomodoro_estimate = params['pomodoro-estimate']
t.save
redirect_to "/show/#{t.id}"
end
end
What kind of controller would I need? How does it know when It is clicked?
I would just like to be pointed in the right direction
Your checkbox in your view is not good I think. You need something like:
<%= f.check_box: field, {}, true %>

rails4 using helper/service and where to put it

I created this class for assembling the text based on the length of the product attributes for sharing on twitter.
My questions:
Is this the good approach to tackle the problem? If not this then what? (where should I put the class and the methods, how to invoke it, etc.)
If this is the good approach then what should be changed? For instance I feel the def twitter_share_text shouldn't be in the product.rb.
show.html.erb
<a class="twitter-share" data-behavior="twitter-share"
data-twittertext="<%= #product.twitter_share_text %>"
data-twitterurl="<%= product_url(#product) %>"
data-twitteranchor>
<i class="fa fa-lg fa-twitter"></i>
</a>
product.rb
def twitter_share_text
TwitterProductShare.new(self).return_text
end
app/services/twitter_product_share.rb
class TwitterProductShare
URL_LENGTH = 23 #defined by twitter API
SPACE_LENGTH = 1
TWITTER_MAX = 140
attr_reader :name, :oneliner
def initialize(product)
#name = product.name
#oneliner = product.oneliner
end
def return_text
if full_length <= TWITTER_MAX
return basic_text
else
return basic_text[0...-(difference + text_end.length)] + text_end
end
end
private
def basic_text
"#{name}: #{oneliner}"
end
def difference
full_length - TWITTER_MAX
end
def full_length
basic_text.length + SPACE_LENGTH + URL_LENGTH
end
def text_end
"..."
end
end
I think code like that belongs into a view helper:
# in app/helpers/product_helper.rb
def twitter_share_link(product)
data = {
behavior: 'twitter-share',
twittertext: TwitterProductShare.new(product).return_text,
twitterurl: product_url(product),
twitteranchor: 'twitteranchor'
}
link_to(class: 'twitter-share', data: data) do
tag(:i, class: 'fa fa-lg fa-twitter')
end
end
In your view use this helper like this:
<%= twitter_share_link(#product) %>
Or you could even return the whole data hash from the TwitterProductShare.

Uninitialized constant error in my controller after adding a presenter

I added this to my controller:
class HtmlreportController < ApplicationController
def index
#report = Report.new
#report_presenter = ReportPresenter.new(#report_presenter)
end
end
Then added this presenter to /app/presenters
# app/presenters/htmlreport_presenter.rb
class ReportPresenter
def initialize(report)
#report = report
end
def pass_fail(view)
arrs = ['onemon.rb','twomon.rb','threemon.rb','fourmon.rb','fivemon.rb']
arrs.each do |arr|
shortname = File.basename("#{arr}", ".rb")
newest_file = Dir.glob("ScriptResults/#{shortname}/*").max
#reporter = File.readlines("/Users/username/Automation/Code/Reports/MonthlyTracking/#{newest_file}")
if #reporter.grep(/test failed/).any?
view.concat content_tag(:div, 'FAILED', class: 'results_fail')
else
view.concat content_tag(:div, 'PASSED', class: 'results_pass')
end
end
end
end
With this in my view:
<% title "HTML Report" %>
<!-- This is where the HTML Report lies -->
<h1>HTML Report for Marines.com Daily Monitoring</h1>
<div>View the grids below for the following results:</div>
<div id="results">
<div class="results_grid">
<div class="results_title">Xbox</div>
<%= #report_presenter.show_credentials(self) %>
</div>
</div>
But, I get this error when running it: uninitialized constant HtmlreportController::Report for the line #report = Report.new
How do I get it initialized to make it recognize the functions in my presenter into my view?

NoMethodError in Lines#show

UPDATE: The answer bellow is correct. Just wanted to update what I did to solve the problem.
First I had to delete all my previous lines in the rails console.
Then I used the bye bug gem in my lines controller at the bottom of the create method to discover where the next bug occurred. I created a test line that I needed to delete again. so I ran
Line.last.delete in console.
This is the way my lines controller create method looks now (working no bugs)
def create
if user_signed_in?
#line = Line.create(line_params)
if #line
if params[:line][:previous_line_id].empty?
#line.story = Story.create
#line.save
else
#line.story = #line.previous_line.story
#line.save
end
redirect_to line_path(#line)
else
flash[:error] = #line.errors
redirect_to line_path(Line.find(params[:line][:previous_line_id]))
end
else
Finally I ran #Lines.each { |line| line.update.attribute(:story_id: 3)}
This gave the necessary association between lines and story.
ORIGINAL POST BELLOW.
I'm getting this error in my rails app. I think that when I create a new line or start a story, it doesn't automatically add it to a story object. I've listed my show.html.erb file as well as my lines controller.rb file.
What am I missing? How do I get the controller to add data to the story object correctly?
Thanks!
I added a few lines of code to my lines controller:
class LinesController < ApplicationController
def new
params[:previous_line_id].nil? ? #line = Line.new : #line = Line.find(params[:previous_line_id]).next_lines.create
#lines = #line.collect_lines
#ajax = true if params[:ajax]
render :layout => false if params[:ajax]
if #line.previous_line
#line.update_attribute(:story_id, #line.previous_line.story.id)
else
story = Story.create
#line.story = story
#line.save
end
end
def create
if user_signed_in?
#line = Line.create(line_params)
if #line
redirect_to line_path(#line)
else
flash[:error] = #line.errors
redirect_to line_path(Line.find(params[:line][:previous_line_id]))
end
else
flash[:error] = "Please sign in or register before creating a line!"
unless params[:line][:previous_line_id].empty?
redirect_to line_path(Line.find(params[:line][:previous_line_id]))
else
redirect_to root_path
end
end
end
# params[:id] should correspond to the first line of the story.
# if params[:deeper_line_id] is not nil, that means that they want to render up to the nested line id
def show
#lines = Line.find(params[:id]).collect_lines
#next_lines = #lines.last.next_lines.ranked
#lines.last.update_attribute(:score, #lines.last.score + 1)
end
def select_next
#line = Line.find(params[:id])
#line.update_attribute(:score, #line.score + 1)
#lines = [#line]
#next_lines = #line.next_lines.ranked
render :layout => false
end
def send_invite
if user_signed_in?
UserInvite.send_invite_email(current_user,Line.find(params[:id]), params[:email]).deliver
flash[:notice] = "Your invite was sent!"
else
flash[:error] = "Please sign in"
end
redirect_to Line.find(params[:id])
end
private
def line_params
params.require(:line).permit(:text, :previous_line_id, :user_id)
end
end
I added these lines to the controller pictured above
if #line.previous_line
#line.update_attribute(:story_id, #line.previous_line.story.id)
else
story = Story.create
#line.story = story
#line.save
end
Here is my show.html.erb file
<div class="row">
<div class="col-lg-2">
</div>
<div class="box-container col-lg-7 ">
<div id="story" class="box">
<% #lines.each do |line| %>
<span class="story-line" data-id="<%=line.id%>"><%= link_to line.text, '#', :class=>"story-line" %></span>
<% end %>
</div>
<div id="next-steps">
<%= render 'next_steps' %>
</div>
<span style="font-size:.9em; margin-bottom:15px; display:block;">*If the links don't work, try refreshing.</span>
</div>
<div class="col-lg-2" style="padding-right:25px;">
<%= render 'invite' %>
Your Fellow Collaborators: <br />
<div class="collaborators">
<% #lines.last.story.collaborators.uniq.each do |collaborator| %>
<%= link_to profile_path(:id => collaborator.id) do %>
<%= image_tag collaborator.profile_image_uri, :class => "prof-icon" %>
<% end %>
<% end %>
</div>
Story model
class Story < ActiveRecord::Base
has_many :lines
has_and_belongs_to_many :collaborators, :class_name => "User", :join_table => "collaborators_stories", :association_foreign_key => :collaborator_id
def first_line
self.lines.first_lines.first_lines.first
end
end
Here is my lines.rb file
class Line < ActiveRecord::Base
scope :first_lines, -> { where previous_line_id: nil}
scope :ranked, -> { order("score + depth DESC")}
belongs_to :user
belongs_to :story
belongs_to :previous_line, :class_name => "Line", :foreign_key => "previous_line_id"
has_many :next_lines, :class_name => "Line", :foreign_key => "previous_line_id"
validates_presence_of :text
after_create :update_depths
def update_depths
line = self.previous_line
while !line.nil?
line.update_attribute(:depth, line.depth + 1)
line = line.previous_line
end
end
def first_line
line = self
while !line.previous_line.nil?
line = line.previous_line
end
line
end
def collect_lines
line = self
lines = [self]
while !line.previous_line.nil?
lines.unshift(line.previous_line)
line = line.previous_line
end
lines
end
end
Problem is orphaned lines in your database. Look for them and associate it to a story, or delete it:
How to find orphaned records:
http://antonzolotov.com/2013/01/26/how-to-find-and-delete-orphaned-records-with-ruby-on-rails.html
Then review the create method to ensure a line should be part of a story:
#short example review activerecord relations
#story = Story.find(params[:story_id])
story.lines.create(line_params)
That should work.
EDIT:
def self.find_orphan_ids
Lines.where([ "user_id NOT IN (?) OR story_id NOT IN (?)", User.pluck("id"), Story.pluck("id") ]).destroy_all
end

Getting data out of a select box and passing it into params

I am doing this for a school project and it is not working. :(
How do I get out the selected[petowner_id] from the view and make it usable in a ruby controller?
How do I make the #selected_pet = params([petowner_id]) in the controller that comes in from the view to function? Currently it renders an error message when I try to set it. :(
I am getting very tired of it not working.
The controller from Pets controller
class PetsController < ApplicationController
# GET /pets
# GET /pets.json
def monsters
#Finds the current user
if current_user
#user = current_user
#pets_kept = [] #why?
##petowner = Petowner.find(params[:petowner][:id])
#if(params[:commit])
#end
#monster = "Eeeep"
#mypets=[]
#all_my_pets = #user.petowners
#options value = 2
#params { selected_petowner[petowner_id]}
#selectpet = params{[selected][petowner_id]}
#petowner = Petowner.find_by_id(params[:id])
#pet = Pet.find_by_id(params[:pet_id])
#Find the petowners that the user currently has
##mypets = #user.petowners
#This is my way of doing things in a C++ fashion, I don't get all ruby things
#user.petowners.each do |pet|
##selected_pet = pet.find(params[:selected])
# if pet.hp != 0
# #pets_kept << pet #Dont recall seeing the << before in ruby but for C++ statement used for cout statements
#if pet.select
# #selected_pet = pet.select
#end
end
##selected_pet = Petowner.find(params[:petowner][:selected])
#end
#selected_pet = 1 ##user.petowners.find(params[:id])
#mypets = current_user.petowners.select{|pet| pet.hp !=0}
#raise "I am here"
##selected_pet = #mypets.find(params[:id][:selected])
##mypets = #pets_kept
end
The code from the view that doesn't go back to the controller variable and set it. :(
<select id="petowner_id" name="selected[petowner_id]">
<%= #all_my_pets.each do |pet| %>
<option value="<%= pet.id %>"><%= pet.pet_name %></option>
<% end %>
</select>
Previous step from pets/monsters view that doesn't work at all from previous collection. :(
<%= form_for :petowner, :url => petowner_fights_path(#selected_pet, #pet) do |f| %>
<p>Select a pet <%#= f.collection_select(:petowner, :petowner_id, #user.petowners, :petowner_id, :pet_name) %></p>
<%= render 'monsterinfo' %>
<div class="outer"></div>
<%= f.submit "Fight Selected Monster" %>
<% end %>
You probably want params[:petowner][:petowner_id]. Definitely don't construct the select with html in a view.
By the way, it's really helpful to see all of the params passed in to a controller action. I tend to raise params.to_yaml when I need to do that.

Resources