I have a form and want to be able to select category & subcategory.
This is an automatic example from seeds.rb:
Examples:
cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
Mayor.create(name: 'Emanuel', city: cities.first)
There is cities.first - but can you do it for cities.sixth or cities.twelfth...?
Is there a different way to do it and connect subcategories with categories in the file?
I would personally advise against using positions to assign subcategories. The possibility exists that there is data on another devs machine or a server.
I generally do it something like:
city = City.find_or_create_by_name(
name: "Chicago"
)
mayor = Mayor.find_or_create_by_city_id(
city_id: city.id,
name: 'Emanuel')
Related
I am creating a Rails api for teachers to rank students based on certain criteria. I have four models: classroom, student, criterion and rank.
Students/Criteria are many to many through Rank
Students/Classroom are many to many
Rank is a join table between Student/Criteria with the additional field of rank, which is an integer between 1-4.
I am able to return the list of Students belonging to a Classroom in a response (1 relation deep) by allowing Classroom.students through in my classroom serializer. How can I return each student's ranks nested within students in my Classroom response (2 relations deep) from my API? Ideal response as below:
Classroom_A:
{
id: "123",
name: "classroom A",
students: [
{ id: "456"
name: Juanita,
gender: female,
ranks: [
{ id: "789",
student_id: "456",
name: "willingness to help others",
rank: "4"
},
{ id: "101",
student_id: "456",
name: "Leadership",
rank: "3"
} ...
]
},
{ id: "232"
name: Billy,
gender: male,
ranks: [
{ id: "789",
student_id: "232",
name: "willingness to help others",
rank: "3"
},
{ id: "101",
student_id: "232",
name: "Leadership",
rank: "3"
} ...
]
}
]
}
Thanks in advance.
A similar question was posted at Rails: Serializing deeply nested associations with active_model_serializers (thanks for the link #lam Phan)
However, the most upvoted answer for that post was not super clear and there was no code example. Super dissapointing. I also looked into the JsonApi adapter and was not able to get the solution I was looking for. In the end I ended up taking the same route as the OP for the linked question: in the serializer I wrote my own function and manually sideloaded the other data that I wanted. I was hoping to do this the "Rails way" but in the end I chose to just get it done.
class ClassroomSerializer < ApplicationSerializer
attributes :id, :name, :school_name, :students
def students
customized_students = []
object.students.each do |student|
custom_student = student.attributes
custom_student['ranks'] = student.student_ranks
customized_students.push(custom_student)
end
customized_students
end
end
I have two models: Producer and Event.
A join model (EventRole) links the two models and stores "role" attribute:
create_table :event_roles do |t|
t.integer :role
t.references :producer, foreign_key: true
t.references :event, foreign_key: true
end
I want to know how list all producers of event X, but returning the "role" of the producer in the event.
Is that even possible?
I achieved to list all producers of an event, but (as expected) it doesn't return the "role":
Producer.joins(:event_roles).where(event_roles: { event_id: 1 })
What is the most elegant way of achieving a result like this?
=> [
{id: 1, name: "Producer 1", role: "manager"},
{id: 5, name: "Producer 5", role: "admin"}
]
When you make the join it does not return a table like a join in the DB would, but the info is there. There are ways of getting that info like:
data = Producer.includes(:event_roles).where(event_roles: { event_id: 1 }).pluck(:id, :name, :role)
Update: you can of course chain my original answer into:
data = Producer.includes(:event_roles).where(event_roles: { event_id: 1 }).pluck(:id, :name, :role).map {|i| {id: i[0], name: i[1], role: [2]} }
Addendum:
One thing I sometimes do if I want a hash data structure that includes the data from both tables I do something like this:
data = EventRole.includes(:producer).where(event_roles: { event_id: 1 }).group_by {|r| r.producer }
This returns a hash instead of an array, where each pair is an object so the form is { => event_role object, etc..}. You can then iterate over the hash and pull which ever columns from each that you need. This is more applicable where you have two tables that have multiple columns you want to be able to access...
data.each do |producer, event_role|
puts "the producer is #{producer.name} and role is #{event_role.role}"
end
=> 'the producer is Producer 1 and role is manager'
'the producer is Producer 5 and role is admin'
Which should return something like:
=> [
[1, "Producer 1", "manager"],
[5, "Producer 5", "admin"]
]
You could then manipulate the data into a form that works for you.
data.map! {|i| {id: i[0], name: i[1], role: [2]} }
=> [
{id: 1, name: "Producer 1", role: "manager"},
{id: 5, name: "Producer 5", role: "admin"}
]
One gotcha here to note: if you have an includes or joins with columns of the same name you need to specify which one you want:
data = Producer.includes(:event_roles).pluck('producers.id', 'event_roles.id')
I have 3 classes with STI and I want to load fixtures for each:
Employee
Admin < Employee
OtherEmployee < Employee
My test_helper files has fixtures :all
and the fixtures are in:
employees.yml
admins.yml
other_employees.yml
and yet only the data from other_employees.yml is loaded into the database. Any idea why or how to fix this?
Fixtures:
#employees.yml
one:
id: 1
name: Name1
full_name: FName1
type: Admin
two:
name: Name2
full_name: FName2
type: Admin
three:
name: Name3
full_name: FName3
type: OtherEmployee
#admins.yml
adminone:
name: Admin1
full_name: FAdmin1
type: Admin
admintwo:
name: Admin2
full_name: FAdmin2
type: Admin
#other_employees.yml
oeone:
name: Oemp1
full_name: FOemp1
type: OtherEmployee
oetwo:
name: Oemp2
full_name: FOemp2
type: OtherEmployee
Which version of Rails are you using? It appears that this was a bug and was fixed in Rails 5 and 4.2
https://github.com/rails/rails/issues/18492
There is also some info in the last comment that may be helpful.
https://github.com/rails/rails/issues/18492#issuecomment-218479248
For anyone still running into this problem you need to add a type
attribute to your fixtures, which represents the STI attribute on your
model. For the provided example this would be:
#teachers.yml
presto:
name: Test Teacher
type: Teacher
#students.yml
testo:
name: Test Person
teacher: presto
type: Student
I want to implement a few simple models to my ruby on rails project. I have the model hierarchy, Topic and Project. A Topic will contain many Projects. I wanted to know what the difference was between adding a "has_many projects" relation in the Topic model vs just adding an array field in the Topic model that stores all of the projects within it.
I am using Ruby on Rails with mongodb as my database and mongoid as the object document mapper.
Let's say in you're Topic model:
has_many :projects
Now, if you query like, #project.topic will execute a single query.
Let's say, you add a column in topic which stores project_ids, e.g.: [1,2,3]
Now if you want to find any individual #topic projects you need to do like this:
first, fetch the #topic.project_ids
Then, for each id query to the Project table, if array contains 3 values then 3 query will run.
So, all is about execution time.
Array Store
you can use to take reference ids of child association. eg
users:
[
{
_id: ObjectId('oii3213ui23uo')
name: 'John',
email: 'jhn#example.com',
project_ids: ['oii3213ui23u1', 'oii3213ui23uo2' ,'oii3213ui23uo3']
}
]
projects:
[
{
_id: ObjectId('oii3213ui23u1'),
title: 'Project 1'
},
{
_id: ObjectId('oii3213ui23u2'),
title: 'Project 2'
},
{
_id: ObjectId('oii3213ui23u3'),
title: 'Project 3'
}
]
has_many
You can use to embed child associations in parent document. eg
users:
[
{
_id: ObjectId('oii3213ui23uo')
name: 'John',
email: 'jhn#example.com',
projects: [
{
title: 'Project 1'
},
{
title: 'Project 2'
},
{
title: 'Project 3'
}
]
}
]
In my rails app, I have a user model and a linkedin_connection model. Linkedin_connection belongs to user and user has_many linkedin_connections.
What's the best way to create a crossover array of connections between user1 and user2?
============== EDIT ============== EDIT ============== EDIT ==============
I realized that this is sort of a different problem than I originally thought. I have 2 arrays of hashes. Each hash has an id element. How can I find the intersection of two hashes by their ids?
Example
user1.linkedin_connections => [{id: "123xyz", name: "John Doe"}, {id: "789abc", name: "Alexander Supertramp"}]
user2.linkedin_connections => [{id: "456ijk", name: "Darth Vader"}, {id: "123xyz", name: "John Doe"}]
cross_connections => [{id: "123xyz", name: "John Doe"}]
How can I calculate "cross_connections?"
Thanks!
What you want is the intersection of the two arrays. In ruby, that's easy, using the & operator:
crossover_connections = user1.linkedin_connections.to_a & user2.linkedin_connections.to_a