Rails - many associations in one view - ruby-on-rails-3

Thanks to stackoverflow users, stackoverflow helped me alot for my project until now. Now I face a new problem.
I already implemented this project http://img7.imagebanana.com/img/cnb46ti2/relationships.png (see Rails - data view from has_many and Has_many_and_belongs_to_many). For connecting positions and skills, I made an has_and_belongs_to_many relationship, because every position has many skills and every skills has many positions and for this table I didn't want to add some columns. The table 'positions_skills' puts both together.
Now I want to add 2 new tables.
current_qualification http://img7.imagebanana.com/img/bimfgvut/UebersichtQualifikationenbistqualifi.png
expected_qualification http://img7.imagebanana.com/img/72p0yj27/UebersichtQualifikationencsollqualif.png
if it's not clear what these tables with the qualification stars do: Every skill in a position has it's own level of qualification (for example for Position 1, you need to be competent in skill 1 alot (5 stars), but for Position 2, you need not so much knowledge about this skill(2 stars)). -> expected_qualification. And every employee is different good in each skill -> current_qualification
Question 1: The table 'expected_qualification' seems similar to the table 'positions_skills'. Am I right that if I add the table 'expected_qualification', than 'position_skills' is not necessary anymore? I just used 'position_skills' for connecting this n:m relationship for viewing employee's skills on show.html.erb, but it's also possible with 'has_many :through' associations if I understood right.
Question 2: Both tables are necessary for viewing these little stars on the view of employee's show.html.erb. (as you can see on my pictures. But right now I'm satisfied with numbers instead of Stars => 4 stars = 4 as integer in column). What did I do?
I created the table 'current_qualification' with rails generate scaffold current_qualification employee_id:integer skill_id:integer qualificationstars:integer
I added code into the models for has_many :through association
I filled the table for current_qualification
and now the tricky part: The employee controller! Because I already have an has_and_belongs_to_many association, the controller looks like this: def show #employee = Employee.find(params[:id], :include => { :position => :skills }) end .... How do I add :include => { :employee => { :current_qualifications => :skills} } for the has_many :through relation now into the already existing code? And which code lets me output the qualificationstars-column from the current_qualification-table for show.html.erb of employee?
Thanks in advance! And sorry for so much questions.

Related

Rails Active Record Query for Double Nested Joins with a Select Call

I have the following schema:
Photos has many Groups has many Users.
I am using this Rails server as a backend to an iOS application and constantly need to push out notifications to all involved users of a group when a photo is added.
I problem is finding the least expensive query to resolve only the User.ids affected.
So far I have
Photo.find(1).groups.joins(:users)
I know that I have to put a select argument after this, but can't figure out the syntax for the life of me.
Given a photo, I am looking for the most efficient way to find a collection of the affected user id's.
Any help would be much appreciated!!!
In your Photo model, you can have another associations called users
has_many :group_users, :through => :groups, :source => :users
Then you can find the users by the following code
#photo = Photo.includes([:group_users]).where("photos.id = ?", 1).first
#affected_users = []
#photo.group_users.map {|user| #affected_users << user.id}
Now the #affected_users contains all the user ids.
users_id = []
Group.where(photo_id: 1).users.collect{|u| users_id << u.id}
puts users_id
As Photo has_many groups, so, groups belongs_to photo and groups table has photo_id as foreign key .
So, please try this.

Need help setting up relationships between models

Rails newbie here struggling with a small project. I am creating a simple ship building tool for a board game I like as an exercise and I am a bit lost.
What do I want to do?
-After creating my Ship model record I want to create the Traits model record that will be associated with the Ship model. After updating a Ship model record I want to update or create the Traits model that will be associated with the Ship model record.
What have I tried?
- Adding the traits to each Ship model record as column variables. I do not think that this is the most effecient way of storing the traits for each of my Ship models. I have a Traits model set up but I do not know how to navigate to it and associate it with my Ship models
What would I like to have when finished?
- An array that is stored in each Ship model record that will list the attributes for each ship with their corresponding values,
i.e. if
trait_list = [trait1 => t1, trait2 => t2, trait3 => t3, trait4 => t4]
ship_traits = [t1, t4].
In the end I would be able to call the traits on my ship diagram page without having to iterate through every single trait, just the ones pertinent to my current model.
I am lost on how I should set up the associations between the models. Any help or kind advice on directions I should be researching would be warmly welcomed. I apologize in advance for my vagueness, again I am a complete newbie.
Cheers,
Nick
I'm not 100% sure this would solve your problem, but you could do something like this:
class Ship < ActiveRecord::Base
has_many :traits
accepts_nested_attributes_for :traits
end
class Trait < ActiveRecord::Base
belongs_to :ship
end
# In your form
- form_for #ship do |f|
- f.fields_for :traits do |ff|
= ff.label :trait_name
= ff.text_field :trait_name
# this will return all the traits for model defined as #ship
#ship.traits
I know it's not an array within the Ship model, but I hear it's a little tricky to set a column in a model to be array. If you want the traits to be unique (as in many ships can have many traits and these traits can belong to many different ships), then you're going to have a has_many :through relationship. If that's the case, let me know and I'll answer again. Or you can take a look at this: http://guides.rubyonrails.org/association_basics.html

BEGINNER: Correct seeds.rb in rails 3

I've just created two models and one "join table". Person, Adress (create_adresses_personss)
class Person < ActiveRecord::Base
has_and_belongs_to_many :streets
end
class Street < ActiveRecord::Base
has_and_belongs_to_many :persons
end
Now I want to add some data to these models in the db/seeds.rb file. The tutorial I follow just adds the objects:
person = Person.create :name => 'Dexter'
street.create[{:streetname => 'street1'},
{:streetname => 'street2'},
{:streetname => 'julianave'},
{:streetname => 'street3'}]
Question 1: Why is persons' data added differently than streets'? Is it just the tutorial that wants to show that there are many ways of adding data in the seeds.rb?
Question 2: The tutorial doesn't make the connections/joins in the seeds.rb. It does that in the rails console;
>>p1 = Person.find(1)
>>s1 = Street.find(1)
>>p1.streets << s1
Can't theese connections be made in the seeds.rb file?
Question 3: Would it be better to do this join with a "rich many_to_many-assocciation"?
Thanks for your time and patience with a beginner ;)
1) The first method is creating one object. The second method is creating multiple objects. However, for the second method you would need to do Street.create, not street.create.
2) Yes, you can do that in the seed file the same way.
3) The "Rich many-to-many" you're talking about is an association with a Join Model, I guess you're talking about. This is opposed to just a join table, which is what has_and_belongs_to_many does. To use a join model, you'll want to look up has_many :through. It's generally considered better to always use a proper join model, however I still use HABTM when I just need a quick, simple association. has_many :through allows for more options and more flexibility, but it is a little more complicated to setup (not that much, though). It's your decision.
One way that I like to create seed data for many-to-many associations is setting up one of the models, the adding a tap block that sets up the other models through the association.
Person.create!(:name => "Fubar").tap do |person|
3.times do |n|
person.streets.create!(:streetname => "street #{n}")
end
# OR
person.streets.create!([
{:streetname => "street 1"},
{:streetname => "street 2"},
... and so on
])
end
All tap is doing is executing the block with the object as it's only parameter. I find it convenient for seeds.
One other tip I would toss out there would be to have your model attribute names spaced on the words with underscores.
:street_name instead of :streetname
The difference is more profound when you start wanting to use some of the ActiveSupport helers that take model attributes and turn them into text strings for use in the UI.
e
:streetname.to_s.titleize # "Streetname"
:street_name.to_s.titleize # "Street Name"
And one last nitpick, you might want your join table to be addresses_people not addresses_persons since the rais inflector is going to pluralize person as people. The same would go for your controller on the Person model, PeopleController instead of PersonsController. Though maybe it will work with persons as well.
:person.to_s.pluralize # "people"
:people.to_s.singularize # "person"
:persons.to_s.singularize # "person"

Rails 3 - multiple associations

I have first table called Cars that contains the informations about color of the car, weight, price etc.
Then I have the second table, for example Other_informations. This table contains another informations about that car from the first table.
In the first table (Cars) is the name of the car. If I need to create an associations between these two tables, I can use:
car.rb
has many :other_informations
otherinformation.rb
belongs_to :car
In this case I have to set the name of one column in the table Other_informations on car_id and the associations will be created.
To this point is everything ok.
But now - I need just one association to add (from the table Other_informations to the table Cars - the same type of associations as the first).
I tried to do something like this:
car.rb
has many :other_informations
otherinformation.rb
belongs_to :car
belongs_to :car2
And then in the view used:
data.car2.name_of_the_car_from_first_table**
But this unfortunately didn't work me... can anyone help me, please, if is something like this possible to do?
Thank you in advance
I am not sure if I understand your question - do you want to have OtherInformation to be shared among different Cars? Like OtherInformation can belong to many different Cars?
You need some kind of many-to-many relationship then. Have a read:
http://guides.rubyonrails.org/association_basics.html#choosing-between-has_many-through-and-has_and_belongs_to_many
EDIT (after reading your comments):
belongs_to car, :class_name => "Car", :foreign_key => "to_col1"
belongs_to another_car, :class_name => "Car", :foreign_key => "to_col2"
That assumes that your OtherInformation has two columns in the database table: to_col1 and to_col2 And here is how associations should work:
other_info = OtherInformation.first
first_car = other_info.car
second_car = other_info.another_car
second_car_name = other_info.another_car.name
#etc...

Help with Rails find_by queries

Say if #news_writers is an array of records. I then want to use #news_writers to find all news items that are written by all the news writers contained in #news_writers.
So I want something like this (but this is syntactically incorrect):
#news = News.find_all_by_role_id(#news_writers.id)
Note that
class Role < ActiveRecord::Base
has_many :news
end
and
class News < ActiveRecord::Base
belongs_to :role
end
Like ennen, I'm unsure what relationships your models are supposed to have. But in general, you can find all models with a column value from a given set like this:
News.all(:conditions => {:role_id => #news_writers.map(&:id)})
This will create a SQL query with a where condition like:
WHERE role_id IN (1, 10, 13, ...)
where the integers are the ids of the #news_writers.
I'm not sure if I understand you - #news_writers is a collection of Role models? If that assumption is correct, your association appears to be backwards - if these represent authors of news items, shouldn't News belong_to Role (being the author)?
At any rate, I would assume the most direct approach would be to use an iterator over #news_writers, calling on the association for each news_writer (like news_writer.news) in turn and pushing it into a separate variable.
Edit: Daniel Lucraft's suggestion is a much more elegant solution than the above.