Calling created Objects in Rails Scaffold - ruby-on-rails

I am new to Rails and creating a football results app, I did a rails generate Scaffold Team name:string form:string then I added a few teams to the table, my next step I tried was to create a Fixtures table that stores teams, so I did rails generate Scaffold Fixture week:string homeTeam:team awayTeam:team homeScore:integer awayScore:integer when I tried to update the database doing a rake db:migrate I am getting an error undefined method:team I understand rails does not like the way I specify them teams as type team.
How can I go about getting this to work, as when creating a fixture I want to be able to choose from a list of teams already stored in a teams table?

As a random aside, the convention in ruby/rails is to use underscores as opposed to camelCase for variables and methods.
On to your actual question! You need to setup relationships yourself in the generated Team and Fixture models. Scaffolding can help you setup the relationships though by getting the correct foreign keys in place.
For the Fixture scaffold, generate it like this:
rails g scaffold fixture week:string home_team_id:integer away_team_id:integer home_score:integer away_score:integer
Note that g is a shortcut for generator and the generator doesn't need anything to be capitalized.
Now, in your Team model you'll want to define your relationship to the Fixture and vice versa (I'm no sports expert, but wouldn't naming it Game make more sense?):
class Team < ActiveRecord::Base
has_many :home_games, :class_name => Fixture, :foreign_key => :home_team_id
has_many :away_games, :class_name => Fixture, :foreign_key => :away_team_id
end
class Fixture < ActiveRecord::Base
belongs_to :home_team, :class_name => Team
belongs_to :away_team, :class_name => Team
end

Related

Rails Unconventional DB Structure, is this problematic for associations?

My company's old team leader had fairly little knowledge of Ruby on Rails and used weird convention for the db structure for associations.
Let's say I have a User model and a Role model, and that a user belongs to a role.
What I would consider typical:
rails g migration AddRoleToUsers role:references
# app/models/user.rb
belongs_to :role
# app/models/role.rb
has_many :users
But I can clearly see that something else has happened.
Whenever I User.new, I get something like:
#<User stuffs, role_id: nil>
In the models I've got
# app/models/user.rb
belongs_to :role, :class_name => 'Role', :foreign_key => :role_id
# app/models/role.rb
has_many :users
This pattern litters a good part of our application. I can tell that these columns are index, but don't actually have a foreign keys.
First question, is this problematic? To me, this implies referential integrity issues.
Second question, how can I add a foreign key after the fact and preserve existing data?
I'm using a gem called data-migration, which I hope can help me preserve the information.
This is just a verbose way of writing what Rails will do automatically by convention.
In the User.role relationship, this:
belongs_to :role, :class_name => 'Role', :foreign_key => :role_id
is equivalent to this:
belongs_to :role
Rails can infer the class_name and foreign_key based on the name of the relationship. It's just a redundancy that won't hurt in this case.
The foreign_key is actually the name of the field that's used to store the id value for the relationship, it's not a database foreign key at all.
You can add a database foreign key for these relationships by creating a migration or each table that you want to update. There's a great answer for that in Adding foreign key to a rails model that gives the step-by-step instructions to do it.

Mapping relationships with custom names in Rails Admin

I am using rails admin, and it works fine except for a pretty big issue. I have custom relationships in mongoid, and rails admin is not allowing me to edit that field.
My relationship definition in mongoid:
class Content
belongs_to :lesson, :inverse_of => :reading_material, class_name: "Lesson"
class Lesson
has_one :reading_material, :inverse_of => :lesson, class_name: "Content"
Note that it is a rather straight forward relationship. But this is what I see this in rails admin:
Surely there must be a way to tell rails admin what to do here?

Declaring associations in Ruby on Rails

Hopefully I don't get flamed for this one too bad - I've tried my very hardest to find an answer to no avail.
I was wondering if someone could help me figure out how to properly declare associations in Ruby on Rails (3). At the moment, I have 3 models:
#room.rb
class Room < ActiveRecord::Base
has_many :check_ins
end
#check_in.rb
class CheckIn < ActiveRecord::Base
belongs_to :user
belongs_to :room
end
#user.rb
class User < ActiveRecord::Base
has_one :check_in
end
So far, I haven't done any migrations to add foreign_key columns to any of my tables (does Rails do this for you?).
I'm confused about why the command CheckIn.first.user returns nil whereas the command User.first.check_in returns SQLite3::SQLException: no such column. The same happens with respect to CheckIn.first.room and Room.first.check_ins, respectively. What would I need to do in order to have User.first.check_in return the CheckIn object associated with the first user and Room.first.check_ins return the set of CheckIns associated with the first Room?
Any help would be GREATLY appreciated.
Charlie
How did you originally generate these models? Did you just make the model files, or did you use rails' model generator (which also generates a migration for you)?
#room.rb
class Room < ActiveRecord::Base
has_many :check_ins
end
#check_in.rb
class CheckIn < ActiveRecord::Base
belongs_to :user
belongs_to :room
end
#user.rb
class User < ActiveRecord::Base
has_one :check_in
has_one :room, :through => :check_in
end
In db/migrations/34612525162_something_something.rb You need to make sure you have migrations that set these tables up for you. The easiest way for you to do it would be to run this command in a console, modify the commands to use the fields you want, the *_id fields are required for your associations to work:
rails generate model user name:string email:string otherfield:integer
rails generate model check_in user_id:integer room_id:integer
rails generate model room number:integer
Note that these will also generate model files for you, since you already have these 3 model files it'll ask you if you want to overwrite them, or skip the files. You can skip them and it should be just fine. If you already had the migrations for part of the data in these models then you can just add the user_id and room_id fields to the check_in model by running this generator instead:
rails generate migration AddIdsToCheckIn user_id:integer room_id:integer
For rails 2.3.x replace rails generate with script/generate. Next you can inspect your migration(s) by opening the files up in db/migrate.rb and modify them there if you need to. Finally, run the migrations:
rake db:migrate
And it should work out for you. Note that I added a has_one, :through => relationship to User - this is so that you can do #user.room without having to make 3 chains: #user.check_in.room
You need to add the migrations yourself (or if you aren't live, you can modify an existing migration). Basically, you need to give the belongs_to side of the relationship a foreign key.
There is absolutely no reason to get flamed don't worry :) It seems here that you are trying to do a one to many association, but you're actually doing a many to many one.
If a user has one check in, it means that he/she has one room. So, you could just have :
user has_one room
room belongs to user
and room has a user_id.
Hope that helps :)

Problem with model associations (1st rails app)

I am developing a small mass administration rails app for our church.
It shall allow the planning of future masses, essentially assigning different tasks to different ministrants (acolyte/server/altar boy?).
One should be able to select serving ministrants (through checkboxes) and assign a task to each ministrant (through option lists), per mass (it does not need to be the same every mass).
My questions are:
1. How would the migrations look like? I.e. which fields of what type are required?
2. How would the model associations look like? Currently, I am assuming 3 classes (Mass, Ministrant, Task).
I found this question: Correct Model Data Structure? (My 1st Rails App)
and it looks similar but I don't really know how to apply the solution on this example...
I'd appreciate your help!
3 models: mass, ministrant and task.
In your console:
rails g model Mass date:datetime
rails g model Ministrant name:string role:string
rails g model Task name:string ministrant_id:integer mass_id:integer
In your ruby files:
class Mass < ActiveRecord::Base
has_many :tasks
has_many :ministrants, :through => :tasks
end
class Ministrant < ActiveRecord::Base
has_many :tasks
has_many :masses, :through => :tasks
end
class Task < ActiveRecord::Base
belongs_to :ministrant
belongs_to :mass
end

Intermediate model to join two seperate models in Ruby on Rails

I am trying to create an intermediate model between two models that I'd like to have a many to many relationship. I am creating an atypical book checkout project and have two models setup Book and Person. I'd like to setup an intermediate model BookCheckOut to track OutDate and ReturnDate.
Dan Singerman provided what looks like the answer I am looking for to the question Ruby On Rails Relationships - One to Many. My inexperience with out model generation and my reliance upon scaffolding are probably causing my problem. I am trying to determine how to not only generate the model but a working database migration that would accompany it.
I am not a rails maestro, but there are two ways to do it that I know of: has_many :through and has_and_belongs_to_many. This article has a decent overview of how. I suspect you would want to use has_many :through so you can access the data in the join table cleanly.
To generate the intermediate model you would do something like:
script/generate model checkouts person_id:int, book_id:int, checked_out:date, returned:date
In your Book model you would add (does Rails know Person --> "People"? I'm guessing yes):
has_many :people, :through => :checkouts
has_many :checkouts, :dependent => true
In your Person model you would add:
has_many :books, :through => :checkouts
has_many :checkouts, :dependent => true
In your Checkout (sorry, I renamed it from your example) model, you would add:
belongs_to :person
belongs_to :book
Use caution with my examples - I am going from memory.

Resources