No Such Column - When Column Exists - ruby-on-rails

Not sure how this is happening but it's saying the column doesn't exist:
SQLite3::SQLException: no such column: element.kind: SELECT COUNT(*) FROM "answers" INNER JOIN "elements" ON "elements"."id" = "answers"."element_id" WHERE "answers"."form_id" = 55 AND "element"."kind" = 6
# element.rb
class Element < ActiveRecord::Base
has_many :answers
end
# answer.rb
class Answer < ActiveRecord::Base
belongs_to :element
belongs_to :form
end
class Form < ActiveRecord::Base
has_many :answers
end
But when I run:
#form.answers.joins(:element).where(:element => {:kind => 6})
I get the sql error above. Not sure what's going on. Any thoughts on what I'm missing?
Thanks!
FYI I'm running rails 3.2.3 with ruby 1.9.3.

The table is elements rather than element as generated by the query ("element"."kind" = 6).
#form.answers.joins(:elements).where(:elements => {:kind => 6})
I would have expected the rest of the query to be generated using the nonexistent element table as well, since you used .joins(:element) instead of .joins(:elements) but perhaps Rails is pluralizing inside .joins() for a belongs_to association.
#form.answers.joins(:element).where(:elements => {:kind => 6})

Related

Attempted Rails db association/query between two models is throwing up errors

I am trying to create an association between two models (Submissions & Agent Activity) whereby each agent can log an activity against a submission without changing the actual submission record itself.
These are my rb files and I believe that these are setup correctly:
class Submission < ApplicationRecord
belongs_to :user, :optional => true
belongs_to :location, :optional => true
has_many :agent_activities
end
class AgentActivity < ApplicationRecord
belongs_to :submission, :optional => true #has submission_id foreign key in table
belongs_to :agent, :optional => true #has agant_id foreign key in
table
end
However, I get lost when it comes to showing this association in the controller. Currently my code looks like this:
#submissions = Submission.where(:Desired_Location => current_agent.Company_Business_Location).pluck(:AgentActivity)
However, I get this error when i do that
PG::UndefinedColumn: ERROR: column "AgentActivity" does not exist
LINE 1: SELECT "AgentActivity" FROM "submissions" WHERE
"submissions... ^ : SELECT "AgentActivity" FROM "submissions" WHERE
"submissions"."Desired_Location" = $1
Additionally, when I run
Submission.where(:Desired_Location =>
current_agent.Company_Business_Location).map(&:AgentActivity)
I get this error:
undefined method `AgentActivity' for #<Submission:0x007fc78601e168>
Did you mean? agent_activities
And when I run:
AgentActivity.joins(:submission).where('submission.Desired_Location'
=> current_agent.Company_Business_Location)
I get this error:
PG::UndefinedTable: ERROR: missing FROM-clause entry for table
"submission"
LINE 1: ..."."id" = "agent_activities"."submission_id" WHERE
"submissio...
^
: SELECT "agent_activities".* FROM "agent_activities" INNER JOIN
"submissions" ON "submissions"."id" =
"agent_activities"."submission_id" WHERE
"submission"."Desired_Location" = $1
You have a typo in class Submission
it should be has_many :agent_activities
.pluck returns an array of values from a database column. You don't have AgentActivity column in submissions table. You can use map instead:
#submissions = Submission.where(:Desired_Location => current_agent.Company_Business_Location).map(&:AgentActivity)
or revert the way you do the query using join:
AgentActivity.joins(:submision).where('submission.Desired_Location' => current_agent.Company_Business_Location)
You may also want to change association naming to snake case to follow Ruby/Rails conventions:
class Submission < ApplicationRecord
belongs_to :user, :optional => true
belongs_to :location, :optional => true
has_many :agent_activities # instead of :Agent_activities
end
EDIT:
map correction:
#submissions = Submission.where(:Desired_Location => current_agent.Company_Business_Location).map(&:agent_activity)
join correction:
AgentActivity.joins(:submision).where('submissions.Desired_Location' => current_agent.Company_Business_Location)

Thinking Sphinx Rails Multiple Association

I have the following models
class Product < ActiveRecord::Base
belongs_to :sub_category
end
class SubCategory < ActiveRecord::Base
belongs_to :category
has_many :products
end
class Category < ActiveRecord::Base
has_many :sub_categories , -> { where("activate = 1") }
end
I need to index my products table.I need to search using category name(which is in category table) and subcategory name(in subcategories table)
ThinkingSphinx::Index.define :product , :with => :active_record do
indexes description
indexes name
indexes merchant_name
indexes sub_category(:sub_category) , :as => :sub_category_name
indexes category(:name) , :as => :cat_name
has sub_category_id
end
The category(:name) is failing.The subcategory is working fine.
Could somebody please help.I tried sub_category.category(:name) but thats also failing
Error Message
ERROR: index 'link_core': sql_range_query: You have an error in your
SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near 'AS cat_name, products.id AS
sphinx_internal_id, 'Product' AS `sphinx_internal_' at line 1
(DSN=mysql://root:***#localhost:3306/xxxx_dev_phase4)
name should be passed as a chained method, not as an argument
indexes sub_category.category.name , :as => "category_name"
Thanks to the owner Pat for helping me out
concerned github thread

Rails - column not found for defined 'has_many' relationship

I define a Post class which can link or be linked to multiple posts. To do this I added a PostLink class which specifies post_to and post_from.
I generated the PostLink class by rails g model post_link from_post:integer to_post:integer and of course rake db:migrate, and added
belongs_to :from_post, :class_name => 'Post'
belongs_to :to_post, :class_name => 'Post'
to the class.
And I also have has_many :post_links in my Post class.
I ran rails console and Post.new.post_links and got nil printed out, which is expected. However after I save a Post using
p = Post.new
p.save
and then run p.post_links, it prints out the following error message:
SQLite3::SQLException: no such column: post_links.post_id: SELECT "post_links".*
FROM "post_links" WHERE "post_links"."post_id" = 1
So anybody know why after saving it to the database post_link can not be accessed?
The has_many :post_links association in Post throws an error because it assumes the foreign key in post_links is post_id by default. Since you are using from_post_id and to_post_id, you will have to find a way to group the post_links for "from" posts and "to" posts to get the total set of post_links for a post.
One approach could be to define two associations on Post and an additional method to add the sets together:
class Post < ActiveRecord::Base
has_many :from_post_links, :class_name => 'PostLink', :foreign_key => :from_post_id
has_many :to_post_links, :class_name => 'PostLink', :foreign_key => :to_post_id'
def post_links
from_post_links + to_post_links
end
end
As another option, you could provide special sql to the association to group the sets in a single query:
class Post < ActiveRecord::Base
has_many :post_links, :finder_sql => Proc.new {
%Q{
SELECT *
FROM post_links pl
WHERE pl.to_post_id = #{id}
OR pl.from_post_id = #{id}
}
}

Rails HBTM join_table overwirting table_name

I'm running Rails 2.3.2 and doing:
class StandardWidget < ActiveRecord::Base
has_and_belongs_to_many :parts, :join_table => "widgets_parts", :association_foreign_key => "widget_custom_id"
end
class Part < ActiveRecord::Base
has_and_belongs_to_many :widgets, :join_table => "widgets_parts", :association_foreign_key => "part_custom_id"
end
p = StandardWidget.find(5)
p.widgets
and get the error
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'widgets_parts.standard_widget_id' in 'where clause': SELECT * FROM `widgets` INNER JOIN `widgets_parts` ON `parts`.part_custom_id = `widgets_parts`.part_custom_id WHERE (`widgets_parts`.standard_widget_id = 5 )
How can I get this working?
The Rails documentation on HBTM says:
WARNING: If you‘re overwriting the
table name of either class, the
table_name method MUST be declared
underneath any has_and_belongs_to_many
declaration in order to work.
What does this mean?
You'll need to use :foreign_key also in the has_and_belongs_to_many call. So in the StandardWidget model you need this:
has_and_belongs_to_many :parts, :join_table => "widgets_parts", :association_foreign_key => "widget_custom_id", :foreign_key => "part_custom_id"
The warning in the docs means that if you are using table names other than 'parts' for the Part model and 'standard_widgets' for the StandardWidget model, then you need to call 'set_table_name' beneath the habtm call.

update_all through an association

I am trying to use update_all through an association, and i am getting mysql errors, anyone know why please?
class Basket < ActiveRecord::Base
has_many :basket_items
has_many :articles, :through => :basket_items
def activate_articles
articles.update_all :active => true
end
end
class BasketItem < ActiveRecord::Base
belongs_to :basket
belongs_to :item
belongs_to :article
end
Mysql::Error: Unknown column 'basket_items.basket_id' in 'where clause': UPDATE `articles` SET `active` = 1 WHERE ((`basket_items`.basket_id = 114))
http://dev.rubyonrails.org/ticket/5353
Looks like there was a problem with n-n associations using has_many :through and using update all. Nothing seems to have been done.
1-n associations do appear to work.
Bug?
dev.rubyonrails moved it's tickets to github's issue tracker. Here is the moved link: https://github.com/rails/rails/issues/522
#nolman posted this help on the ticket
#daicoden and I at #square were pairing on this and we were able to put something together along the lines of:
class Comment
class << self
def trash_all
sql = "UPDATE #{quoted_table_name} "
add_joins!(sql, {})
sql << "SET #{sanitize_sql_for_assignment({:trashed => true})} "
add_conditions!(sql, {})
connection.execute(sql)
end
end
end
Now you can call todolist.comments(:conditions => {:trashed => false}).trash_all
This results in the following SQL:
UPDATE `comments` INNER JOIN `todos` ON `todos`.id = `comments`.todo_id SET `trashed` = 1 WHERE (`comments`.`trashed` = 0 AND `todos`.`todolist_id` = 968316918)
Hope this helps!

Resources