heroku run rails db:migrate - heroku

After doing heroku run rails db:migrate, I got this error amongst the stacktrace:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation
"categories" does not exist:
CREATE TABLE "products" ("id" serial primary key, "title" character varying, "description" character varying, "category_id"
integer, "picture" character varying, "video" character varying,
"created_at"
timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_fb915499a4"
FOREIGN KEY ("category_id") REFERENCES "categories" ("id"))
Then I ran heroku run:detached rake db:migrate and it worked.
But when I go to the site's url, I got this error:
ActiveRecord::StatementInvalid in WelcomeController#index
PG::UndefinedTable: ERROR: relation "products" does not exist LINE 1: SELECT "products".* FROM "products" ORDER BY "products"."cr... ^ : SELECT "products".* FROM "products" ORDER BY "products"."created_at" ASC LIMIT $1
Edit:
class WelcomeController < ApplicationController
def index
end
end
Also the error points to this line:
#all_products = Product.order(created_at: :asc).last(4)
Defined in application_controller.rb like so:
def getProducts
#all_products = Product.order(created_at: :asc).last(4)
end
The #all_products variable was used in welcome/index.html.erb to display the last 4 uploaded products.
It was called like so:
<div class="text-center">
<% if #all_products.present? %>
<% #all_products.each do |p| %>
<a href="<%= p.picture() %>" data-toggle="lightbox" data-gallery="example-gallery" data-title="<%= p.title %>">
<%= image_tag(p.picture.url, size: '200x200', class: 'rounded') %>
</a>
<% end %>
<% end %>
</div>

A rake db:migrate runs in a one-off process, your web process will have already booted and cached the original DB schema, you need to restart your app following the migration being run to recache the new schema.

Related

ajax-datatables-rails How to add buttons in ajax response

My problem is that I don't know how to add different buttons that remain in a condition using the gem for server side processing ajax-datatables-rails. For example before trying to do sever side processing I had this in my view.
<% if current_user.sales_manager? || current_user.admin? %>
<td>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
bill_sale_path(bill_sale),
:method => :delete %>
</td>
<% end %>
and following the tutorial in the main page of the gem, in bill_sale_datatable.rb I have this.
def data
records.map do |record|
[
link_to('Show', bill_sale_path(record), class: 'btn-xs btn-link'),
record.customer.name,
record.seller.name,
l(record.date_sold, format: :short),
record.payment_type.name,
record.payed,
number_to_currency(record.total),
CONDITION AND BUTTON HERE
]
end
end
Then, how do I use the server side processing to provide different buttons that belongs to an if condition?
While I haven't used the gem, I have used datatables with Rails and this is what I did:
Store the button as a variable before the array and then just call the variable in the array.
records.map do |record|
record_button = ''
record_button = button_to('A', button1_path) if condition1
record_button = button_to('B', button2_path) if condition2
record_button = button_to('C', button3_path) if condition3
record_button = button_to('D', button4_path) if condition4
[
link_to('Show', bill_sale_path(record), class: 'btn-xs btn-link'),
record.customer.name,
record.seller.name,
l(record.date_sold, format: :short),
record.payment_type.name,
record.payed,
number_to_currency(record.total),
record_button
]
end
You could also use a case statement if that suited your needs.
Make sure you add
def_delegator :#view, :button_to
To the top of your file as per:
https://github.com/jbox-web/ajax-datatables-rails#using-view-helpers

Find children of a user supplied id in a self-join association

I have a functioning self-join relationship where a guideline has many children and belongs to a parent. I need to let the user supply an ID via an html form, and then find its children, or its parent (in a separate form of course) When I run in rails console as
#guidelines = Guideline.find(4)
#guidelines.children
I get the proper children, and when i do
#guideline.parent
I get the proper parent.
For some reason when I define a form as
<%= form_tag(guidelines_path, :method => "get", id: "search-form") do %>
<td><%= label_tag(:seeChildren, "See Immediate Children")%></td>
<td><%= text_field_tag :seeChildren, params[:seeChildren], placeholder: "Enter ID" %></td>
<td><%= submit_tag "Search", :name => nil %></td>
<% end %>
(app/views/index.html.erb)
And in the controller i say
if params[:seeChildren]
#guideline = Guideline.find(params[:seeChildren])
#guideline.children
(app/controllers/guidelines_controller.rb)
I get the following error in my rails served in Terminal:
Started GET "/guidelines?utf8=%E2%9C%93&seeChildren=4" for 127.0.0.1 at 2014-10-18 14:25:58 -0500
Processing by GuidelinesController#index as HTML
Parameters: {"utf8"=>"✓", "seeChildren"=>"4"}
Guideline Load (0.3ms) SELECT "guidelines".* FROM "guidelines" WHERE "guidelines"."id" = ? LIMIT 1 [["id", 4]]
Rendered guidelines/index.html.erb within layouts/application (4.1ms)
Completed 500 Internal Server Error in 85ms
ActionView::Template::Error (undefined method `each' for nil:NilClass):
62: <th>Guideline Text</th>
63: </tr>
64:
65: <% #guidelines.each do |guideline| %>
66: <tr>
67: <td><%= guideline.id %></td>
68: <td><%= guideline.guide_desc %></td>
app/views/guidelines/index.html.erb:65:in `_app_views_guidelines_index_html_erb__3376611479089996349_70360485758280'
Rendered /Users/john.dodson/.rvm/gems/ruby-2.1.3#global/gems/actionpack-4.1.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.7ms)
Rendered /Users/john.dodson/.rvm/gems/ruby-2.1.3#global/gems/actionpack-4.1.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.3ms)
Rendered /Users/john.dodson/.rvm/gems/ruby-2.1.3#global/gems/actionpack-4.1.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (21.6ms)
Any ideas? I appreciate the help. Ive posted a couple questions and was unsuccessful usually because I wasn't supplying enough information, so please let me know if you need to see another file.
It looks like you may have forgotten to define #guidlines in your controller, which would explain why you are getting the undefined method 'each' for nil:NilClass error message when attempting to call .each on #guidelines in <% #guidelines.each do |guideline| %>
Yes, Same as JBMILGROm said, you forgot to mention #guidelines in controller.
In addition to using the wrong singular/plural on guidelines, I found out that I needed to cast a single object into an array. So find a guideline, then call children and cast the results into an array. so in the controller I say:
if params[:seeChildren]
#guideline = Guideline.find(params[:seeChildren])
#guidelines = Array.wrap(#guideline.children())
and magic, my query works. Posting this here so other people having a similar problem can find the truth.

Rails 3: Loop shows more records than there should be

Not exactly sure of what to call this issue. Still new to rails.
Situation: An auction contains many lots.
I'm showing an auction's lots in a url like /auctions/3/lots/.
View:
<ul>
<% #lots.each do |lot| %>
<li><%= lot.auction_id %>: <%= lot.id %></li>
<% end %>
</ul>
Outputs this:
<ul>
<li>3: 1</li>
<li>3: </li>
</ul>
I only have one lot in my database. Not sure where the extra loop instance is coming from.
This happens on any lot listing no matter which auction I'm looking at.
Also,
<%= #lots.length %> displays 2
<%= #lots.size %> displays 2
<%= #lots.count %> displays 1
My lots_controller looks like this:
def index
#auction = Auction.find(params[:auction_id])
#lots = #auction.lots
end
def create
#auction = Auction.find(params[:auction_id])
#lot = #auction.lots.build(params[:lot])
if #lot.save
redirect_to auction_lots_path, :notice => 'Lot was successfully created.'
else
render :action => "index"
end
end
My models:
class Auction < ActiveRecord::Base
...
has_many :lots
end
class Lot < ActiveRecord::Base
belongs_to :auction
...
end
The ...s are just attr_accesssible and validates lines.
The log when I hit the page was requested, here it is.
Started GET "/auctions/8/lots" for 127.0.0.1 at 2013-02-13 16:35:51 -0500
Processing by LotsController#index as HTML
Parameters: {"auction_id"=>"8"}
Auction Load (0.1ms) SELECT "auctions".* FROM "auctions" WHERE "auctions"."id" = ? LIMIT 1 [["id", "8"]]
Lot Load (0.2ms) SELECT "lots".* FROM "lots" WHERE "lots"."auction_id" = 8
[#<Lot id: 18, description: "1923 Morgan", lot_number: 1, auction_id: 8, created_at: "2013-02-13 17:20:04", updated_at: "2013-02-13 17:20:04">]
Rendered layouts/_messages.html.erb (0.1ms)
Lot Exists (0.2ms) SELECT 1 AS one FROM "lots" WHERE "lots"."auction_id" = 8 LIMIT 1
Rendered lots/index.html.erb within layouts/application (9.4ms)
Completed 200 OK in 21ms (Views: 17.8ms | ActiveRecord: 0.5ms)
Update:
Someone mentioned that it looks like I'm using #auction.lots.build somewhere.
And yes, I am. I have a form on the same page (index) where I can add lots.
<%= form_for(#auction.lots.build, :url => auction_lots_path(#auction)) do |f| %>
...
<% end %>
Changing #auction.lots.build got rid of the extra row, although now I can't create lots successfully. I'm not sure what to do. I probably have to set up something in the index method of the lots_controller, but I don't know what.
Any help is appreciated.
This would happen in your create method if the lot failed to save. Because you used #auction.lots.build, that appends a lot record to the auction. If it doesn't save properly, it's still there unsaved. That explains why the "mystery" one doesn't have an id, and also why:
<%= #lots.size %> displays 2
<%= #lots.count %> displays 1
#lots.count is a database query, but #lots.size is just the size of the array in memory.
I would probably do something more like this in the create action:
def create
#auction = Auction.find(params[:auction_id])
#lot = #auction.lots.create!(params[:lot])
redirect_to auction_lots_path, :notice => 'Lot was successfully created.'
rescue ActiveRecord::RecordInvalid
render :action => "index"
end
... but of course others will prefer using if/else rather than rescuing the exception. There are other ways around this. You could do #auction.reload.lots to cull the unsaved one, but that's a little wierd. The normal rails thing to do in this case is re-render the form with the validation errors displayed and ask the user to fix them and try creating again.
This should help:
def create
params[:lot].merge!({:auction_id => params[:auction_id]})
#lot = Lot.new(params[:lot])
if #lot.save
redirect_to auction_lots_path, :notice => 'Lot was successfully created.'
else
render :action => "index"
end
end

rails 3.2 update has_many :through

I'm pretty close on this one but caught up on a minor detail. I am trying to update a has_many :through relationship. When I submit the edit form I am unable to extract the appropriate attribute that I want to update. The loop that updates the qty shipped is not updated that field with the correct value. How can I extract only the qty_shipped attribute from the params[:product_shipments] hash?
This is the contents of my params[:product_shipments] hash that the update action is working with
"product_shipments"=> {"82"=>{"qty_shipped"=>"234"},
"83"=>{"qty_shipped"=>"324"},
"84"=>{"qty_shipped"=>"324"}},
"commit"=>"Update Shipment", "id"=>"250"}
Which has all the information I need to update the shipment because the #shipment.product_shipments loop limit the update to only the shipment_id applicable. My problem is that this is the following sql called by update action
ProductShipment Load (0.3ms) SELECT `product_shipments`.* FROM `product_shipments` WHERE `product_shipments`.`shipment_id` = 250
BEGIN
UPDATE `product_shipments` SET `qty_shipped` = 1 WHERE `product_shipments`.`id` = 82
COMMIT
BEGIN
UPDATE `product_shipments` SET `qty_shipped` = 1 WHERE `product_shipments`.`id` = 83
COMMIT
BEGIN
UPDATE `product_shipments` SET `qty_shipped` = 1 WHERE `product_shipments`.`id` = 84
COMMIT
And here is the update action that produces the above sql:
def update
#shipment = Shipment.find(params[:id])
#shipment.update_attributes(params[:shipment])
#shipment.product_shipments.each do |shipment|
shipment.update_attributes(:qty_shipped=> params[:product_shipments])
end
respond_with #shipment, :location => shipments_url
end
Using rbates nested_forms gem is not preferred because I want to figure this out for the purposes of learning how rails works.
<%= hidden_field_tag("product_shipments[][#{product_shipment.id}]") %>
<%= hidden_field_tag("product_shipments[][product_id]", product_shipment.id) %>
<%= text_field_tag "product_shipments[][qty_shipped]", product_shipment.qty_shipped,:class => 'shipment_qty_field'%>&nbsp<%=#product.product_name %>
#shipment.product_shipments.each do |product_shipment|
product_shipment.update_attributes(:qty_shipped => params[:product_shipments][product_shipment.id][:qty_shipped])
end
You shouldn't have to do all this, just use Nested Forms. This is Rails!
http://railscasts.com/episodes/196-nested-model-form-part-1
Your params should look like this
{:product_shipments => { 79 => { :qty_shipped => 450 }, 80 => { :qty_shipped => 35 } }, :shipment_id => 1 }
To get that you should name your fields like this
<input name="product_shipments[79][qty_shipped]" value="450" />
<input name="product_shipments[80][qty_shipped]" value="35" />
To generate that,
<% #shipment.product_shipments.each do |product_shipment| %>
<%= text_field_tag "product_shipments[#{product_shipment.id}][qty_shipped]", product_shipment.qty_shipped || 0 %>
<% end %>

Postgres: Error using GROUP BY and ORDER (on heroku)

I am trying to solve my heroku problem which it seems to have problem of
We're sorry, but something went wrong.
We've been notified about this issue and we'll take a look at it shortly.
Is there any mistake I have and how to overcome it?
How can I interpret these Heroku logs?
ActionView::Template::Error (PGError: ERROR: column "microposts.created_at" must appear in the GROUP BY clause or be used in an aggregate function
2011-11-14T17:33:07+00:00 app[web.1]: : SELECT category FROM "microposts" GROUP BY category ORDER BY microposts.created_at DESC):
2011-11-14T17:33:07+00:00 app[web.1]: 2: <% #categories= Micropost.select("category").group("category")%>
2011-11-14T17:33:07+00:00 app[web.1]: 3: <% unless #categories.nil? %>
2011-11-14T17:33:07+00:00 app[web.1]: 4:
2011-11-14T17:33:07+00:00 app[web.1]: 5: <ul><% #categories.each do |category| %>
2011-11-14T17:33:07+00:00 app[web.1]: 6: <li><%= link_to category.category, :controller =>"microposts", :category => category.category, :method => 'category_list' %></li>
2011-11-14T17:33:07+00:00 app[web.1]: 7: <% end %>
2011-11-14T17:33:07+00:00 app[web.1]: 8: </ul>
micropost model (New added)
class Micropost < ActiveRecord::Base
belongs_to :users
default_scope :order => 'microposts.created_at DESC'
attr_accessible :title,:content,:category
validates :user_id, :presence => true
validates :title, :presence => true,
:length => {:maximum =>500}
validates :content, :presence => true,
:length => {:maximum =>3000}
validates :category, :presence => true
end
Your immediate problem is that you're producing invalid SQL for PostgreSQL:
SELECT category FROM "microposts" GROUP BY category ORDER BY microposts.created_at DESC
Your ORDER BY doesn't match the rest of your query. You can't use a column in a grouped query unless that column is also grouped or if the column appears in an aggregate function, that's what the error message means. The reason is that PostgreSQL won't know which row's created_at to use when a group of rows are combined by the GROUP BY clause; some databases will just silently pick a row on their own, PostgreSQL prefers to be strict and wants you to remove the ambiguity yourself.
Try specifying the order yourself:
#categories = Micropost.select("category").group("category").order("category")
Another option is to use DISTINCT instead of GROUP BY to avoid duplicates:
#categories = Micropost.select('DISTINCT(category)')
BTW, you really shouldn't be doing that sort thing in a view, you might want to move that to your controller.
Your real problem is that you're developing on top of one database while deploying on another. I'd recommend that you switch your development environment to PostgreSQL 8.3 (if you're deploying to a Heroku shared database) or PostgreSQL 9.0 (if you're deploying to a dedicated database).
Have you been developing your app on MySQL? Heroku doesn't include MySQL. It uses postgreSQL. Look at this question here - PostgreSQL GROUP BY different from MySQL?
I quote -
MySQL's totally non standards compliant GROUP BY can be emulated by Postgres' DISTINCT ON. Consider this :
mysql :
SELECT a,b,c,d,e FROM table GROUP BY a
This delivers 1 row per value of a (which one, you don't really know). Well actually you can guess, because MySQL doesn't know about hash aggregates, so it will probably use a sort... but it will only sort on a, so the order of the rows could be random. Unless it uses a multicolumn index instead of sorting. Well, anyway, it's not specified by the query.
postgres :
SELECT DISTINCT ON (a) a,b,c,d,e FROM table ORDER BY a,b,c
This delivers 1 row per value of a, this row will be the first one in the sort according to the ORDER BY specified by the query. Simple.

Resources