undefined method `Ques_id' for #<Questionnaires:0x007fcc490c88f8> - ruby-on-rails

In my application Questionnaires its my controller in that one datatype is t.integer "Ques_id" its not able to acess in my index page.when i run the index page then i will get NoMethodError in Questionnaires#index error. How to solve this error?
table
class CreateQuestionnaires< ActiveRecord::Migration
def up
create_table :questionnaires do |t|
#t.column "id", :string, :limit => 25
t.integer "Ques_id"
t.string "Qname"
t.string "Header"
t.string "Description"
t.string "username"
end
end
def down
drop_table :questionnaires
end
end
controller
class QuestionnairesController < ApplicationController
# layout false
layout "admin"
def index
#questionnaires = Questionnaires.sorted()
end
def view
#questionnaires= Questionnaires.find(params[:id])
end
def new
#questionnaires= Questionnaires.new()
end
def create
# Instantiate a new object using form parameters
#questionnaires = Questionnaires.new(questionnaires_params)
# Save the object
if #questionnaires.save
# If save succeeds, redirect to the index action
flash[:notice] = "questions saved successfully."
redirect_to(:action => 'index')
else
# If save fails, redisplay the form so user can fix problems
render('new')
end
end
def edit
#questionnaires = Questionnaires.find(params[:id])
end
def update
# Find an existing object using form parameters
#questionnaires= Questionnaires.find(params[:id])
# Update the object
if #Questionnaires.update_attributes(questionnaires_params)
# If update succeeds, redirect to the index action
flash[:notice] = "questions updated successfully."
redirect_to(:action => 'view', :id => #questionnaires.id)
else
# If update fails, redisplay the form so user can fix problems
render('edit')
end
end
def delete
#Questionnaires= Questionnaires.find(params[:id])
end
def destroy
questionnaires = Questionnaires.find(params[:id]).destroy
flash[:notice] = "questions '#{Questionnaires.name}' destroyed successfully."
redirect_to(:action => 'index')
end
private
def questionnaires_params
# same as using "params[:subject]", except that it:
# - raises an error if :subject is not present
# - allows listed attributes to be mass-assigned
params.require(:questionnaires).permit(:Ques_id,:Qname, :Header, :Description, :visible)
end
end
index page here i got error
<% #page_title = "Questionnaires" %>
<div class="Questionnaires index"
<h2>Questionnaires </h2>
<%= link_to("Add New questions", {:action => 'new'}, :class => 'action new') %><br>
<div><%= pluralize(#questionnaires.size, 'questionnaires') %> found</div>
<th>Questionnaires</th>
<table class="listing" summary="Questionnaires list">
<tr class="Header">
<th>Ques_id</th>
<th>Qname</th>
<th>Header</th>
<th>Description</th>
<th>Actions</th>
</tr>
<% #questionnaires.each do |objQuestionaire| %>
<tr class="<%= cycle('odd', 'even') %>">
<td><%= objQuestionaire.Ques_id %></td>
<td><%= objQuestionaire.Qname %></td>
<td><%= objQuestionaire.Header %></td>
<td><%= objQuestionaire.Description %></td>
<!--td><%= objQuestionaire.username %></td-->
<td class="actions">
<%= link_to("view", {:action => 'view', :id => objQuestionaire.id}, :class => 'action view') %>
<!-- <%= link_to("view", '#', :class => 'action view') %>-->
<!-- <%= link_to("Edit", '#', :class => 'action edit') %>-->
<%= link_to("edit", {:action => 'view', :id => objQuestionaire.id}, :class => 'action edit') %>
</td>
<%end %>
##its my error page
Showing /home/cabox/workspace/app_1/app/views/questionnaires/index.html.erb where line #20 raised:
undefined method `Ques_id' for #<Questionnaires:0x007fcc490c88f8>
Extracted source (around line #20):
17
18
19
20
21
22
23
<% #questionnaires.each do |objQuestionaire| %>
<tr class="<%= cycle('odd', 'even') %>">
<td><%= objQuestionaire.Ques_id %></td>
<td><%= objQuestionaire.Qname %></td>
<td><%= objQuestionaire.Header %></td>
<td><%= objQuestionaire.Description %></td>
Rails.root: /home/cabox/workspace/app_1
Application Trace | Framework Trace | Full Trace
app/views/questionnaires/index.html.erb:20:in `block in _app_views_questionnaires_index_html_erb__3549852765576469128_70257686505360'
app/views/questionnaires/index.html.erb:17:in `_app_views_questionnaires_index_html_erb__3549852765576469128_70257686505360'

It is looking for a Ques_id column in your table(Questionnaires) which is not been migrated yet. So only it throws
`NoMethodError`
Please update your database by doing
rake db:migrate
which will migrate all the required fields defined in the migration file to your database so that it will not throw error.

Related

Undefined method for object defined in controller Rails

I have a view with a form and a table that displays some data from the database. Whenever I try to access the object from my controller in my view I get undefined method domain for "https://www.lookagain.co.uk/":String. But if do <%#savedHTML = ScrapedPage.all%> everything works fine. I know the I should not do that in the view as it defeats to purpose of MVC but I don't seem to fin a fix.
View:
<%= stylesheet_link_tag "masterstyles.css" %>
<% #url = 'default' %>
<%= form_for #url, :url => {:controller => "page_scraper", :action => "scrape"} do |f| %>
<%= f.text_field (:url) %>
<%= f.submit "Scrape" %>
<% end %>
<%#domain ='default'%>
<%#date ='default'%>
<%= form_for #domain, :url => {:controller => "page_scraper", :action => "compare"} do |f| %>
<%=select_tag 'domain', options_for_select(#savedHTML.collect{ |u| [u.domain, u.domain] })%>
<%=select_tag 'date', options_for_select(#savedHTML.collect{ |u| [u.created_at, u.created_at] })%>
<%= f.submit "compare" %>
<% end %>
<div class="subjects index">
<h2>FGH Page Scraper</h2>
<table class="listing" summary="Links list">
<tr class="header">
<th>ID</th>
<th>link</th>
<th>Created at</th>
<th>Updated at</th>
</tr>
<% #savedHTML.each do |page| %>
<tr>
<td><%= page.id %></td>
<td><%= page.domain %></td>
<td class="center"><%= page.created_at %></td>
<td class="center"><%= page.updated_at %></td>
<td class="actions">
<%= link_to("Delete", {:controller => 'page_scraper', :action => 'delete', :id => page.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
Controller:
class PageScraperController < ApplicationController
require 'nokogiri'
require 'open-uri'
require 'diffy'
require 'htmlentities'
def scrape
#url = watched_link_params[:url].to_s
puts "LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOG#{#url}"
#page = Nokogiri::HTML(open(#url))
coder = HTMLEntities.new
#encodedHTML = coder.encode(#page)
create
end
def index
#savedHTML = ScrapedPage.distinct.pluck(:domain)
end
def show
#savedHTML = ScrapedPage.distinct.pluck(:domain)
end
def new
#savedHTML = ScrapedPage.new
end
def create
#savedHTML = ScrapedPage.create(domain: #url, html: #encodedHTML, css: '', javascript: '')
if #savedHTML.save
puts "ADDED TO THE DATABASE"
redirect_to(root_path)
else
puts "FAILED TO ADD TO THE DATABASE"
end
end
def edit
end
def upadate
end
def delete
#savedHTML = ScrapedPage.find(params[:id])
end
def destroy
#savedHTML = ScrapedPage.find(params[:id])
#savedHTML.destroy
redirect_to(root_path)
end
def compare
#domain = params[:domain].to_s
puts #domain
redirect_to(root_path)
#timestamp
end
def watched_link_params
params.require(:default).permit(:url)
end
def compare_params
params.require(:domain).permit(:domain)
end
end
The problem is that in your controller you are saving only string-values to #savedHTML variable (pluck will give you only an array of attributes from given objects). Therefore you cant ask "some_string".domain because String class doesn't have a domain method.
If you have a domain method on ScrapedPage object then in your controller action (index or show - whatever you are dealing with) you should replace
#savedHTML = ScrapedPage.distinct.pluck(:domain)
with
#savedHTML = ScrapedPage.select(:domain).distinct
The latter will give you unique ScrapedPage objects based on domain value. Look here for further info and examples.
NB! also a tip for refactoring:
Use strong parameters under private section. Also, if you have the same query in your controller twice in different actions then it is better to make it in before_action like this:
class PageScraperController < ApplicationController
before_action :set_saved_html, only: %i[index show]
def index
end
def show
end
private
def watched_link_params
params.require(:default).permit(:url)
end
def compare_params
params.require(:domain).permit(:domain)
end
def set_saved_html
#savedHTML = ScrapedPage.select(:domain).distinct
end
end

Rails: No route matches [POST] "/specials/1"

This is the error I'm getting:
No route matches [POST] "/specials/1"
I understand that it's not able to produce the post route, or it isn't available.
Here's my view/form code:
<%= form_for(:special, :url => {:action => 'update', :id => #special.id}) do |f| %>
<table class="table table-responsive table-striped table-condensed table-hover" summary="Special form fields">
<tr>
<th>Order</th>
<td><%= f.text_field :order, class: "form-control" %></td>
</tr>
<tr>
<th>Name</th>
<td><%= f.text_field :name, class: "form-control" %></td>
</tr>
<tr>
<th>Description</th>
<td><%= f.text_field :description, class: "form-control" %></td>
</tr>
<tr>
<th>Fine Print</th>
<td><%= f.text_field :fine_print, class: "form-control" %></td>
</tr>
<tr>
<th>Active</th>
<td><%= f.text_field :active, class: "form-control" %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Update Special") %>
</div>
<% end %>
Heres's my controller code:
class SpecialsController < ApplicationController
def index
#specials = Special.sorted
end
def show
#special = Special.find(params[:id])
end
def new
#special = Special.new
end
def create
#Instantiation of object using form parameters
#special = Special.new(special_params)
#Save the object
if #special.save
#If success, redirect to index action
redirect_to(:action => 'index')
else
# Redisplay the form so user can fix problems
render('new')
end
end
def edit
#special = Special.find(params[:id])
end
def update
#Find an existing object using form parameters
#special = Special.find(params[:id])
#Update the object
if #special.update_attributes(special_params)
#If succeeds, redirect to index action
redirect_to(:action => 'show', :id => #special.id)
else
# If update fails, redisplay the form so user can fix problems
render('edit')
end
end
def delete
end
private
def special_params
params.require(:special).permit(:name, :description, :fine_print, :active, :order)
end
end
I noticed that there is an update path:
PATCH /specials/:id(.:format) specials#update
I can't figure out why the post route isn't being applied. It's looking for the right #special instance, but it doesn't seem to have the route available. Any advice?
Usually when updating a record, we do a patch request to the route. Your form should look like this:
<%= form_for(#special) do |f| %>
Rails will determine the correct route is PATCH /specials/:id based on the fact that #special has been persisted to the database.
If you decide to use this same form as a partial in your new view, just make sure to add this to your controller:
def new
#special = Special.new
end
That way whether you are on the new route or the edit route, there will always be a #special object for form_for to infer whether to POST to /specials or PATCH /specials/:id

Couldn't find HourLog without an ID rails 4 record not found

I'm trying to display only records created by the logged in user from the database, and don't know how to go about doing that. I get an error when I try to access the database and identify specific data to pull from it.
Hours Controller
class HoursController < ApplicationController
before_action :require_user
def new
#hour = HourLog.where(:user_id => current_user.id)
#entry = HourLog.all
end
def create
#hour = HourLog.new(hour_params)
#hour.User_id = current_user.id if current_user
#hour.status = 'Pending'
if #hour.save
redirect_to '/dashboard'
end
end
private
def hour_params
params.require(:hour_log).permit(:assignment, :hours, :supervisor, :date,)
end
end
Hours View (new.html.erb)(field to enter data into database)
<% #entry.each do |hour| %>
<tr>
<td><%= hour.assignment %></td>
<td><%= hour.hours %></td>
<td><%= hour.supervisor %></td>
<td><%= hour.date %></td>
<td><%= hour.status %></td>
</tr>
<% end.empty? %>
<%= form_for(#hour, url: hours_path) do |f|%>
<tr>
<td id="dashfield"><%=f.text_field :assignment, :placeholder=> "Assignment"%></td>
<td id="dashfiled"><%=f.text_field :hours, :placeholder => "Hours"%></td>
<td id="dashfield"><%=f.text_field :supervisor, :placeholder=> "Supervisor/Location"%></td>
<td id="dashfield"><%=f.date_field :date, :placeholder=> "Date"%></td>
<%=f.hidden_field :status, :value => "Pending" %>
<%=f.hidden_field :User_id, :value => current_user.id %>
<td id="dashbtn"><%=f.submit 'Create' %></td>
</tr>
<%end%>
Error:
Started GET "/dashboard" for 127.0.0.1 at 2015-08-10 17:29:08 -0500
Processing by HoursController#new as HTML
User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 4]]
Completed 404 Not Found in 18ms
ActiveRecord::RecordNotFound (Couldn't find HourLog without an ID):
app/controllers/hours_controller.rb:4:in `new'
Thanks!
I think this function:
def new
#hour = HourLog.where(:user_id => current_user.id)
#entry = HourLog.all
end
should be changed to:
def new
#hour = current_user.hour_logs.new
#entry = current_user.hour_logs.all
end
Assuming the model user is configured with has_many :hour_logs.
as in your models, user have many hour_logs the table hour_logs must have a column user_id minding the capitalization
to change the column name from User_id to user_id you need to create a new migration.
in the command prompt navigate to the rails app folder and execute:
rails g migration fixcolumn1
this will generate a file in your-app-path/db/migrate called some-date_fixcolumn1.rb
edit this file so the following is present:
def change
rename_column :hour_logs, :User_id, :user_id
end
after that go back to the prompt and execute
rake db:migrate
It should work from there
Assuming User has_many hour_logs and HourLog belongs_to users ...
visit "/hours/new?user_id=123" to fill out your new hour_log form. Upon successful save user will be redirect to "/users/:user_id" page where they will see only records created by current logged in user ... which is what you asked for :) Hope this helps!
#config/routes.rb
Rails.application.routes.draw do
get '/hours/new', to: "hours#new"
post '/hours/create', to: "hours#create"
get '/users/:user_id', to: "users#index"
end
#controllers/users_controller.rb
class UsersController < ApplicationController
def index
#user_hours = User.find(params[:user_id]).hour_logs
end
end
#controllers/hours_controller.rb
class HoursController < ApplicationController
before_action :require_user
def new
#user_hours = User.find(params[:user_id]).hour_logs
end
def create
User.find(params[:user_id]).hour_logs.create!(
assignment: params[:assignment],
hours: params[:hours],
supervisor: params[:supervisor],
date: params[:date],
status: params[:status]
)
redirect_to "/users/#{params[:user_id]}"
end
end
#hours view
<% #user_hours.each do |hour| %>
<tr>
<td><%= hour.assignment %></td>
<td><%= hour.hours %></td>
<td><%= hour.supervisor %></td>
<td><%= hour.date %></td>
<td><%= hour.status %></td>
</tr>
<% end %>
<%= form_for "", url: {controller: 'hours', action: 'create'}, method: "post" do |f|%>
<tr>
<td id="dashfield"><%=f.text_field :assignment, :placeholder=> "Assignment"%></td>
<td id="dashfiled"><%=f.text_field :hours, :placeholder => "Hours"%></td>
<td id="dashfield"><%=f.text_field :supervisor, :placeholder=> "Supervisor/Location"%></td>
<td id="dashfield"><%=f.date_field :date, :placeholder=> "Date"%></td>
<%=f.hidden_field :status, :value => "Pending" %>
<%=f.hidden_field :user_id, :value => params[:user_id] %>
<td id="dashbtn"><%=f.submit 'Create' %></td>
</tr>
<%end%>

How can I pass the parameters to controller correctly?

From show view: I'd like to pass the shown message's id to discard action and trash the message.
From index view: I'd like to pass the checked messages' ids to discard action and trash them all at once.
But I only can trash one record at once even if I check multiple and submit from index view.
How can I archive both 1 and 2 with the same action????
Routes
match 'messages/discard(/:id)' => 'messages#discard', :via => :post , :as => :discard_messages
index view
<%= form_tag(:action => discard, :via => 'post') do %>
<% #messages.each do |m| %>
<tr>
<td><%= check_box_tag "id",m.id %></td>
<td><%= m.last_message.id %></td>
<td><%= 'unread' if m.is_unread?(current_user) %></td>
<td><%= m.last_message.created_at.to_s(:jp) %></td>
<td><%= m.last_sender.username %></td>
<td><%= link_to m.subject, show_messages_path(:id => m, :breadcrumb => #box) %></td>
</tr>
<% end %>
<%= submit_tag "discard", :class => 'btn' %>
<% end %>
show view
<%= link_to 'Discard', discard_messages_path(#messages), :class => 'btn', :method => 'post' %>
controller
def discard
conversation = Conversation.find_all_by_id(params[:id])
if conversation
current_user.trash(conversation)
flash[:notice] = "Message sent to trash."
else
conversations = Conversation.find(params[:conversations])
conversations.each { |c| current_user.trash(c) }
flash[:notice] = "Messages sent to trash."
end
redirect_to :back
end
use the [] naming in your html, which rails will then make available as an array in the params
index.html.erb
<td><%= check_box_tag "message_id[]", m.id %></td>
controller
# ...
else
conversations = Conversation.where("id IN (?)", params[:message_id][])
# ...
to simplify things further I would remove the conditional in your action and create two separate actions
routes
resource :messages do
member do
post 'discard' # /messages/:id/discard
end
collection do
post 'discard_all' # /messages/discard_all?message_id[]=1&message_id[]=22
end
end

Simple quantity function problems, shopping cart

I just picked up Agile Web Development with Rails 3rd Ed., and I'm going thru the Depot Application chapters, I'm attempting to create a simple Edit quantity function, and delete function. I've had luck with the delete function but no luck with the edit quantity function.
I'm going to provide a lot of information, so please don't feel overwhelmed. I've found this to be a challenging problem.
To add_to_cart.html.erb
<div class="cart-title">Your cart</div>
<table>
<% for item in #cart.items %>
<tr>
<td><% form_for #cart.items, :url => {:action => "cart_update", :id => "#{item.getinventoryid}"} do |f| %>
<%= f.text_field :quantity, :size => '3' %>
<%= f.hidden_field :id, :value => "#{item.getinventoryid}" %>
<%= f.submit 'cart_update' %>
<% end %></td>
<td><%=h item.quantity %> ×</td>
<td><%=h item.title %></li></td>
<td><%=h item.description %></td>
<td class="item-price"><%= number_to_currency(item.price) %></td>
<td><%= link_to 'remove', {:controller => 'inventories', :action => 'remove_cart_item', :id => "#{item.getinventoryid}"} %></td>
</tr>
<% end %>
<tr class="total-line">
<td colspan="4">Total</td>
<td class="total-cell"><%= number_to_currency(#cart.total_price) %></td>
</tr>
</table>
<%= button_to "Checkout", :action => 'checkout' %>
<%= button_to 'Empty cart', :action => 'empty_cart' %>
inventories_controller:
def cart_update
#inventory = Inventory.find(params[:id])
#cart = find_cart
#cart.increment_inventory_quantity(params[:inventory])
end
def remove_cart_item
inventory = Inventory.find(params[:id])
#cart = find_cart
#cart.remove_inventory(inventory)
redirect_to_index("The item was removed")
end
Cart.rb model
attr_accessor :items
def increment_inventory_quantity(id, quantity)
inventory_to_increment = #items.select{|item| item.inventory == inventory}
# We do this because select will return an array
unless product_to_increment.empty?
inventory_to_increment = inventory_to_increment.first
else
# error handling here
end
inventory_to_increment.quantity = quantity
end
def remove_inventory(inventory)
#items.delete_if {|item| item.inventory == inventory }
end
cart_item.rb model
attr_accessor :inventory, :quantity
def getinventoryid
#inventory.id
end
This produces strange results:
Notice the quantity 16 appears in both items from my loop (#Fail). When I submit the form a ArgumentError in InventoriesController#cart_update wrong number of arguments (1 for 2) error is returned. Parameters being passed:
{"commit"=>"cart_update",
"_method"=>"put",
"authenticity_token"=>"sH1tWXTJPltpSq5XaAkww7259IR5ZiflnqSFB2Zb0IY=",
"id"=>"50",
"cart_item"=>{"quantity"=>"16",
"id"=>"50"}}
You are getting the wrong number of arguments error because you are passing one argument to #cart.increment_inventory_quantity in the controller method. That method requires two arguments.
# In your controller:
def cart_update
#inventory = Inventory.find(params[:id])
#cart = find_cart
#cart.increment_inventory_quantity(params[:inventory]) # you are passing one thing
end
# Then in your model:
def increment_inventory_quantity(id, quantity) # the method wants two things
# ...
Possibly you intended to do something like this:
def cart_update
#inventory = Inventory.find(params[:cart_item][:id])
#cart = find_cart
#cart.increment_inventory_quantity(#inventory.id, params[:cart_item][:quantity])
end
Are you sure it's form_for( #cart.items ) and not form_for( item )?

Resources