With a lot of delay a post what was our second day with this pet app, since then we have done a lot of things, that somehow I’ll try to post in following days.
We create the relation between models
We begin adding the relation that implies that one location can have many events but one events is in one location
we edit the model event.rb and add
belongs_to: location
then we open model location.rb and all
has_many: events
then we proceed with events and categories, which have a relation where one event can have many categories and one category many events associated
Edit event.rb and add
has_many: categories
has_and_belongs_to_many: categories
edit category.rb and add
has_and_belongs_to_many: events
Now we are going to introduce in the console the first data to check if the relations are ok
We create an event with just name
Event.create :name => "Rails girls at CBase", :date =>"2012-11-11"
now we check if the event was created
event = Event.first
event.save
Next we create a location and add its capacity
location = Location.new
location.capacity = "200"
location.save
location.reload
Now we are going to have some fun using polymorphism. We saw that there are many contact data shared between Organizers and Locations both have, name, description, address, email, link, image, so it makes no sense to have the same attributes repeated in two tables, so we create a table just for the descriptions, where we will store the data from Organizers and Locations.
To use polymorphism we will need an intermediate table where it will be associated the id of the description with the id of the Location or Organization, this will enable us to decide which description to choose when showing a Organizer or a Location, so we create a migration called
MakeDescriptionPolymorphic which will look like:
$rails generate migration MakeDescriptionPolymorphic
class MakeDescriptionPolymorphic < ActiveRecord::Migration
def up
add_column :descriptions, :descriptable_type, :string
add_column :descriptions, :descriptable_id, :integer
end
def down
remove_column :descriptions, :descriptable_type
remove_column :descriptions, :descriptable_id
end
end
type in the terminal rake:migrate so the changes take effect
where descriptable_type refers to Organizer or Location and descriptable_id to the id of the Organizer or the Location
then we had to create another migration to solve a mistake we had made before when creating the Event-Category table, we didn’t take into account the order and the plurals, so we had a event_categories tables but the convention says that a many_to_many relation the table has to be in plural and the names order alphabetically, so we did this migration RenameEventCategoryTable
class RenameEventCategoryTable < ActiveRecord::Migration
def up
rename_table :event_categories, :categories_events
end
def down
rename_table :categories_events, :event_categories
end
end
type in the terminal rake:migrate so the changes take effect
We also need to rename the file event_category.rb to events_category
sonduk@sonduk:~$ mv app/models/event_category.rb app/models/events_category.rb
And modify inside the model
class EventsCategory < ActiveRecord::Base
^
Next we want to see the location where the event takes place, for that we need to recover the name of the location, but the name is not in location table, but associated to description table, so we need to assure that description is not nil for any location
for that we do in location model
before_create :ensure_presence_of_description
then to fetch the name of the location directly we use method delegate, also defined in location model
delegate :name, :address, :link, :email, :to => :description
We had some issues, sorry this time can’t really explain the reasons (not sure) but the solution was to remove the timestamps from the category events migration so we did
$rails generate migration RemoveTimestampsFromCategoriesEvents
that generates the following migration
class RemoveTimestampsFromCategoriesEvents < ActiveRecord::Migration
def up
remove_column :categories_events, :created_at
remove_column :categories_events, :updated_at
end
def down
add_column :categories_events, :created_at, :datetime
add_column :categories_events, :updated_at, :datetime
end
end
Now all the models should be ok, or at least we hope so 🙂 … so check a bit in the console
and now we change a bit the views, so we begin to see some of the stuff done
We want to create as a link the info in the link field
<%= link_to @event.link, @event.link %>
we want to show in the events the location as a link to the location description page
<p>
<b>Location:</b>
<%= link_to @event.location.name, @event.location %>
</p>
And we want to show the list of categories associated to the event
<b>Category:</b>
<ul>
<%- @event.categories.each do |category| %>
<li> <%= link_to category.name, category %></li>
<%- end %>
</ul>