Rails Nested Forms - One to One with One to Many nested - ruby-on-rails

I have a problem and I have a bit of a hard time explaining it. Here are my models:
class Company < ActiveRecord::Base
has_one :publisher
has_one :developer
end
class Publisher < ActiveRecord::Base
belongs_to :company
has_many :games
end
class Developer < ActiveRecord::Base
belongs_to :company
has_many :games
end
class Game < ActiveRecord::Base
belongs_to :publisher
belongs_to :developer
end
Basically a Company can be a Developer or Publisher or both. Then I can call Company.publisher.games to see all the games the company published, and Company.developer.games to see the games they developed.
The problem is I don't know the most efficient way to nest the forms for this.
Basically when I am at /company/new, I want to have a form for the company, which in turn has a box where I can specify multiple game IDs for either the Publisher or the Developer aspect of the company. I can't seem to figure out how I can just do #company.update_attributes(params[:company]) and have that take a nested form and create a publisher and or developer with multiple associated games.

Related

ActiveRecord association through multiple tables

I have the following schema for my Rails app :
A project has many reviews, each of those reviews is filled out by a unique User to calculate a global score.
We could say that "An Organization of Users handles many Entities that have many Projects which are reviewed by the Users".
As you can see, I have a circular reference since I linked the tables "Users" & "Reviews".
After many tries and many search, I just can't manage to associate a User to a Review...Here is what I did so far:
1. Creation of an association table "UserReviews"
2. Model User
class User < ApplicationRecord
belongs_to :organization
####
has_many :user_reviews
has_many :reviews, through: :user_reviews
end
3. Model Review
class Review < ApplicationRecord
belongs_to :project
##
belongs_to :user_reviews
has_one :user, through: :user_reviews
end
4. Model UserReview
class UserReview < ApplicationRecord
belongs_to :user
belongs_to :review
end
I want to be able to get user.reviews or review.user.
Basically...I have to admit I'm lost despite the documentation. I never had to deal with this kind of issue.
Many thanks for your help!
Why do you need UserReview model here? I suppose Review model suffices your use case.
Change the Review model to:
class Review < ApplicationRecord
belongs_to :project
belongs_to :user
end

Has_many association with specific values: how-to?

I want to build a (toy/learning) RoR app for managing personal boardgame library, but I'm stuck when I try to define a correct data structure.
Basically, a user owns a library with many games. For each game, the user defines a price and a rating.
So I have a simple model for user, with name:text attribute and a model for game, with title:text attribute.
I also have a library model, that references the user model, and have a one-to-many relationship with games.
Now I'm not sure how to define the attributes rating and price for the games on the library.
Simple idea is to define report as join table from library and games with attributes rating and price, but I feel this solution so... clumsy.
Any other ideas?
No clumsy at all. It is the right solution, indeed.
You need a many-to-many association between library and game since a library can have many games and a game can be in many libraries.
As you said, create the model report referencing both library and game plus the columns rating and price, then define the has_many :through associations:
class Report < ApplicationRecord
belongs_to :library
belongs_to :game
end
class Game < ApplicationRecord
has_many :reports
has_many :libraries, through: :reports
end
class Library < ApplicationRecord
belongs_to :user
has_many :reports
has_many :games, through: :reports
end

Tournament -> Team -> Player Associations

I'm a relative beginner to Rails, but am learning as I go. I'm trying to create a Tournament Entry portal, where a team would enter players for a given tournament. I've done a bit of reading about associations, but am having some trouble wrapping my head around how to apply them in this instance.
As a basic overview:
One tournament, has many teams.
Each team has many players
Therefore one tournament also has many players (through the teams
entered)
Here's my code for this, but I'm not sure it's right because I'm unable to get any tournament_ids associated to players.
(tournament.rb)
class Tournament < ApplicationRecord
has_many :teams
has_many :players, :through => :teams
end
(team.rb)
class Team < ApplicationRecord
belongs_to :tournament
has_many :players
end
(player.rb)
class Player < ApplicationRecord
has_one :team
has_one :tournament, :through => :team
end
Within the Players table there is both team_id & tournament_id fields, however I'm only able to populate the team_id field through association when I try in console.
I'm wondering if there's something amiss with my associations.
The usage of 'belongs_to', 'has_many', 'has_one' depends on the data model in database of course.
If you have team_id foreign key in players table, then you need to define Player class as:
class Player < ApplicationRecord
belongs_to :team
has_one :tournament, :through => :team
end
In addition, I really believe that Tournament <-> Team should have many-to-many association (if team can participate in many tournaments of course). I would suggest adding model TeamTournament and define final model structure as:
class Tournament < ApplicationRecord
has_many :team_tournaments
has_many :teams, :through => :team_tournaments
has_many :players, :through => :teams
end
class TeamTournament < ApplicationRecord
belongs_to :team
belongs_to :tournament
end
class Team < ApplicationRecord
has_many :team_tournaments
has_many :tournaments, :through => :team_tournaments
has_many :players
end
the Player class should have belongs_to associations with Team and Tournament
class Player < ApplicationRecord
belongs_to :team
belongs_to :tournament
end
OK. I assume your question is about your models associations rather than how to set up association for getting tournament_id from player and so on. So I'll try to hand you some tips about your project and associations could be set up for it.
As I got your portal idea... You want the tournament to has many teams and the team to has many players. But then you want to get tournament_id from player. I believe you don't want to do that because in real life tournament indeed may "has" some players but every single player don't has to belong to some tournament. He can take part in many tournaments. So you don't need to set up association for that. Same thing with tournament and teams. But since team has the player he has to belong to that team. So you need association for that.
Wrapping up my setup for you will be like:
(tournament.rb)
class Tournament < ActiveRecord::Base
has_many :teams
end
(team.rb)
class Team < ActiveRecord::Base
has_many :players
end
(player.rb)
class Player < ActiveRecord::Base
belongs_to :team
end
And an example about how you can get the tournament where certain team take part in without the direct association:
team = Team.first # just take some team
Tournament.includes(:teams).where(teams: { id: team.id })
The same way you can achieve your other goals (get the tournament certain player belongs to and so on). But such cases don't need associations. Associations are needed when the object relates to another conceptually.

User and Team modeling

I have been doing some searching around Google and this site for some ways to go about constructing some models for an application I am working on.
I plan to have Users and Teams. A user can join a team and one team only. A team can obviously have many users. Also, I want to add a 'leader' role inside the team that is assigned to the User who creates a Team but can later be passed on to another User who is already a part of that team.
I have seen some examples of models for something like this and saw a few like this:
class User < ActiveRecord::Base
has_one :team
has_many :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :team
end
class Team < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
Why is the Membership model necessary? I have seen it in a few examples and I am not sure I quite follow the logic of why it is in there and what it is doing.
Also, if I did something like has_one :leader in the Team model and had the Leader model, would that be considered the best practice for determining a leader in a Team? It seems like a bit much to have an entire model/table for Leader.
The Memberships model is allowing for a many-to-many relationship there. It's acting as the join table. It would allow Users to belong to many Teams and Teams to have many Users.
Sounds like you just want a one-to-many though?
class User < ActiveRecord::Base
belongs_to :team
end
class Team < ActiveRecord::Base
has_many :users
end
I'll have to double check this part but you can use additional parameters to specify the models in your assocation if they don't match up with the name you need. So Team could have a leader that's just a User model.
class Team < ActiveRecord::Base
has_many :users
has_one :leader, :class_name => "User", :foreign_key => "user_id"
end
the rails guides page on associations has a good summary including the part about the :class_name and other options
http://guides.rubyonrails.org/association_basics.html#the-has_many-association

Complex Pricing on Products in Rails

Rails newbie here so please dont bang your head too much when you see what I'm having issues with (It should probably be straightforward!)
I'm working on an app whereby clients have services based on products (VPS) for sale. Whilst the number of actual products are minimal, they are highly configurable and pricing is dependant on a few factors:
Ram / HDD Size
The Location of the server (which may also change the currency)
Any product 'add-ons'.
I'm having an issue with how I'd actually go about implementing pricing this (generating a price from the various factors to add to a users service) - and after speaking to people they've given me different answers which has left me even more confused.
If it helps, I have my models like so:
class Product < ActiveRecord::Base
has_many :services
has_many :prices
has_many :addons
belongs_to :product_cat
end
class Service < ActiveRecord::Base
belongs_to :product
belongs_to :user
belongs_to :location
end
class Location < ActiveRecord::Base
has_one :currency
has_many :services
end
Any help would be appreciated.
Cheers.
First of all, I think you should take some time to think a bit more about your database structure.
What type of relation do you have between Products and Services?
From what I understand, a product can have several services, and a service can be active for several products. This sound like a n->m association to me.
If it's like that, you should have your tables set-up like this:
class Product < ActiveRecord::Base
has_many :product_services
has_many :services, through: :product_services
has_many :prices
has_many :addons
belongs_to :product_cat
end
class ProductServices < ActiveRecord::Base
belongs_to :product
belongs_to :service
end
class Service < ActiveRecord::Base
has_many :product_services
has_many :products, through: :product_services
belongs_to :user
belongs_to :location
end
class Location < ActiveRecord::Base
has_one :currency
has_many :services
end
With this setup, getting the price for a product should be pretty straightforward.
If your product has a base price, and all of your services have a price, then the total price of the product is the sum of the base price and of all the individual services prices.
Now that you have your associations in place, you can access them with the following:
product.services # returns all of the services for the specific product.
product.services.sum(:price) # returns the sum of all the individual prices of each service.
I hope this will help you in implementing your pricing solution. It can be a complex problem, but Rails provides a number of way to make it easier. As a side note, you should really have a look at the active_record documentation, it's full of information that will make your life easier.
Cheers!

Resources