polymorphic rails association fails on inherited class? - ruby-on-rails-3

I'm having trouble doing the reverse polymorphic association when I have an inherited class. Anyone know what's going on?
ruby-1.9.2-rc2 > Label.first
=> #<Label id: 1, owner_id: 1, owner_type: "Student", name: "Lorem", created_at: "2011-01-23 05:02:29", updated_at: "2011-01-23 05:02:29">
ruby-1.9.2-rc2 > Label.first.owner
=> #<Student id: 1, email: "alice1#example.com", ..., avatar_updated_at: nil>
ruby-1.9.2-rc2 > Label.first.owner.labels
=> []
class Student < User
has_many :labels, :as => :owner
class Label < ActiveRecord::Base
belongs_to :owner, :polymorphic => true
Note: just for good measure (not that this should be any different, but just in case...)
User.find(1).labels
=> []
Also
l = Label.find(4)
=> #<Label id: 4, owner_id: 2, owner_type: "Student", name: "sit", created_at: "2011-01-23 05:02:29", updated_at: "2011-01-23 05:02:29">
ruby-1.9.2-rc2 > l.owner_type = "User"
=> "User"
ruby-1.9.2-rc2 > l.save
=> true
ruby-1.9.2-rc2 > Student.find(2).labels
=> [#<Label id: 4, owner_id: 2, owner_type: "User", name: "sit", created_at: "2011-01-23 05:02:29", updated_at: "2011-01-23 07:13:37">]

Still not sure why it was failing (well, I can guess, given the Student/User dichotomy), but for future reference this hack works:
has_many :labels, :conditions => ["owner_type = ?", "Student"],
:foreign_key => "owner_id"

Related

Single query for two join statements

In plain English, I am trying to find all agents who have a license in the state of Ohio and have an industry name of Professional Beer...
Here are my models:
class Agent < ApplicationRecord
validates :name, :phone_number, presence: true
has_many :licenses
has_and_belongs_to_many :carriers
end
class Carrier < ApplicationRecord
validates :name, presence: true
has_and_belongs_to_many :industries
end
class Industry < ApplicationRecord
validates :name, presence: true
has_and_belongs_to_many :carriers
end
class License < ApplicationRecord
validates :state, presence: true
belongs_to :agent
end
I have worked out both ends of the queries:
2.5.3 :057 > Carrier.joins(:industries).where('industries.name = "Professional Beer Taste-Tester"')
Carrier Load (0.5ms) SELECT "carriers".* FROM "carriers" INNER JOIN "carriers_industries" ON "carriers_industries"."carrier_id" = "carriers"."id" INNER JOIN "industries" ON "industries"."id" = "carriers_industries"."industry_id" WHERE (industries.name = "Professional Beer Taste-Tester") LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Carrier id: 6, name: "Iguana Insure", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Carrier id: 10, name: "Polaris International Risk", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">]>
and...
2.5.3 :061 > Agent.joins(:licenses).where('licenses.state = "OH"')
Agent Load (0.4ms) SELECT "agents".* FROM "agents" INNER JOIN "licenses" ON "licenses"."agent_id" = "agents"."id" WHERE (licenses.state = "OH") LIMIT ? [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Agent id: 5, name: "Scot Morar", phone_number: "(279) 691-4148", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 6, name: "Cassey Beier", phone_number: "(474) 777-3615", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 12, name: "Jani VonRueden", phone_number: "1-444-626-9429", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 14, name: "Gemma Ritchie", phone_number: "594.170.4795", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 20, name: "Milo Klein", phone_number: "677.137.7019", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 40, name: "Ellie Cole", phone_number: "(720) 543-2929", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 52, name: "Dayna Hilll", phone_number: "(220) 218-4786", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 54, name: "Barton Nikolaus II", phone_number: "1-881-355-1168", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 61, name: "Miss Katrice Oberbrunner", phone_number: "1-658-789-4817", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 66, name: "Hobert Ryan DDS", phone_number: "501-950-6320", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, ...]>
=> #<ActiveRecord::Relation [#<Carrier id: 6, name: "Iguana Insure", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Carrier id: 10, name: "Polaris International Risk", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">]>
Now I need to combine both of these so I am returning a list of agents. So the desired result would return a list of agents:
=> [#<Agent id: 118, name: "Deangelo Hermiston", phone_number: "1-756-870-1969", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 119, name: "Wm Breitenberg", phone_number: "223-404-1670", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">, #<Agent id: 120, name: "Elsy Vandervort", phone_number: "908.065.9697", created_at: "2019-08-21 15:38:30", updated_at: "2019-08-21 15:38:30">]
For a single query there isn't adequate relations setup. So what can be done is
ohio_agents_id = Agent.joins(:licenses).where('licenses.state = "OH"').pluck(:id)
desired_agents = Agent.joins(carriers: :industries).where(industries: { name: "Professional Beer Taste-Tester" }, id: ohio_agents_id)
Below will get desired result in single query
Agent.joins(:licenses, carriers: :industries).where('licenses.state = "OH"').where('industries.name = "Professional Beer Taste-Tester"')

How to get has_and_belongs_to_many relation objects together

I have HABTM associated tables like below.
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :users
end
How do I get User(s) with associated Groups together(nested), like below
{
id: 8,
name: "John",
groups: [
{
id: 17,
name: "Alpha Group",
user_id: 8
},
{
id: 18,
name: "Bravo Group",
user_id: 8
}
],
},
Is there a nice rails way of doing this?
I can manually create object like above but it would be nice to have a simpler query.
def index
#group = Group.find(params[:id])
respond_to do |format|
format.html
format.json { #group.users.map do |user|
user.to_json(:include => :groups)
end
}
end
end
It'll return an array like:
[
{
"id":1,
"email":"admin#example.com",
"groups":[
{
"id":1,
"name":"Yo"
},
{
"id":2,
"name":"Bro"
},
]
},
{
"id":2,
"email":"valar#example.com",
"groups":[
{
"id":1,
"name":"Arya"
},
{
"id":2,
"name":"Stark"
},
]
}
]

how to do i check whether the association is vaild or not on rails console

=>s = User.new
=> #<User id: nil, first_name: nil, last_name: nil, email: nil, address: nil, type_of_user: nil, created_at: nil, updated_at: nil>
2.2.0 :015 > o.publisher_id = s
=> #<User id: nil, first_name: nil, last_name: nil, email: nil, address: nil, type_of_user: nil, created_at: nil, updated_at: nil>
2.2.0 :016 > o.publisher_id = 6
=> 6
2.2.0 :017 > s = User.create(:first_name => "Bostnss")
(0.2ms) BEGIN
(0.2ms) ROLLBACK
=> #<User id: nil, first_name: "Bostnss", last_name: nil, email: nil, address: nil, type_of_user: nil, created_at: nil, updated_at: nil>
2.2.0 :018 > o.publisher_id = 5
for that you have to first know that what are the associations that are you using for that you have to apply this
code
in my app i have three models user , order and articles
so for checking the associations i use this
a = Article.new
after insert the data and
use command
a.realod
after that
a.user [the name that i given in the association ]
if it works that means that associations works

Autosave issue in rails 3.2

In the given code,
class Supplier < ActiveRecord::Base
has_one :criteria, foreign_key: "crt_sup_id", :autosave => true
self.primary_key = 'sup_id'
end
class Criteria < ActiveRecord::Base
belongs_to :supplier, foreign_key: "crt_sup_id"
self.primary_key = 'crt_id'
self.table_name = 'criterias'
end
autosave is not working when I am submitting the form. Supplier records are created but not Criteria.
Form code
class SupplierForm < Netzke::Basepack::Form
def configure(c)
c.model = 'Supplier'
super
c.items = [
{field_label: "Name", name: :bname},
{field_label: "Detail", name: :detail},
{
layout: :hbox, border: false, defaults: {border: false}, items: [
{
flex: 1,
layout: :anchor,
defaults: {anchor: "-8"},
items: [
{field_label: "Value 1", name: :criteria__val_one, xtype: :checkbox, nested_attribute: true},
{field_label: "Value 2", name: :criteria__val_two, xtype: :checkbox, nested_attribute: true}
]
}
]
}
]
end
end
Controller code
def index
end
Solved with the help of Netzke author. Replace criteria__val_one with criteria_val_one and
criteria__val_two with criteria_val_two. Create virtual attributes in the model class. Now all the values entered in the form is accessible with these virtual attributes and can be saved. Credit goes to Max Gorin. Thanks for the great work (Netzke)

Mongoid querying

I have some application on RoR with Mongodb database. I use Mongoid mapper. Model post.rb
class Post
include Mongoid::Document
field :title, :type => String
field :text, :type => String
embeds_many :comments
end
Model comment.rb
class Comment
include Mongoid::Document
field :name, :type => String
field :content, :type => String
embedded_in :post, :inverse_of => :comments
end
In database this post with some comment has next structure:
{
"_id": ObjectId("4ecbeacf65430f0cef000003"),
"comments": {
"0": {
"name": "my name",
"content": "example content",
"_id": ObjectId("4ecbead365430f0cef000005")
},
"1": {
"name": "some name",
"content": "example content",
"_id": ObjectId("4ecbead665430f0cef000007")
},
"2": {
"name": "some name",
"content": "example content",
"_id": ObjectId("4ecbeada65430f0cef000009")
}
},
"text": "example text",
"title": "example title"
}
And, for example, in database was a few posts with my comments.
I need to find all posts, where "name": "my name", i.e. I need to find all editable by me posts.
It should appear as a array of comments instead of a hash. See my example below.
Also, as per the mongoid docs use the new style field declarations.
comment.rb:
class Comment
include Mongoid::Document
field :name, type: String
field :content, type: String
embedded_in :post
end
post.rb:
class Post
include Mongoid::Document
field :title, type: String
field :text, type: String
embeds_many :comments
end
Rails Console:
p = Post.new(:title => "title", :text => "post")
c1 = Comment.new(:name => "Tyler", :comment => "Awesome Comment!")
c2 = Comment.new(:name => "Joe", :comment => "comment 2")
p.comments << c1
p.comments << c2
p.save
Mongo Console:
> db.posts.findOne()
{
"_id" : ObjectId("4ecd151d096f762149000001"),
"title" : "title",
"text" : "post body",
"comments" : [
{
"name" : "Tyler",
"comment" : "Awesome Comment!",
"_id" : ObjectId("4ecd1569096f762149000002")
},
{
"name" : "Joe",
"comment" : "comment 2",
"_id" : ObjectId("4ecd157f096f762149000003")
}
]}
Then, to do the query you want, which I think was "comments posted by me?":
> db.posts.findOne({"comments.name": "Tyler"})
Also, I would add an index to the comments.name field:
> db.posts.ensureIndex({"comments.name": 1})