As with every rails project, in the beginning rails gives you a basic project setup using the model-view-controller pattern.
Let's try:
./ > rails -d mysql survey
The -d option is important to specify the usage of a database right at the start. In general, I use mysql for this, and the provided database.yml may need a bit tweeking the first time, but will soon be functional for many rails projects.
To create and test the database, you want to check with:
./survey/ > rake db:create
if there is no error message.
Coming back to our MVC pattern, at the moment, the directories /survey/app/models, /survey/app/views and /survey/app/controllers are still empty.
Basic resources (what the combination of a view-model-controller often is), can easily be done with scaffolding.
So, let's make a resource for our "question" and one resource for a "choice".
script/generate scaffold question whatabout:string
script/generate scaffold choice desc:string
With
rake db:migrate
we create our new tables in the database.
Now, we need to associate a choice wih a question. We want to select the choices that a user can enter in the survey. So, we use a m:n relationship between choices and questions. (The steps behind this are explained more in detail here, here and here).
So, to implement the associations, we need to modify our table and the models accordingly.
First, we create a helper table with:
script/generate model questions_choice
In the new migration, we add references to our "choices" and "questions" tables like this:
class CreateQuestionsChoices < ActiveRecord::Migration
def self.up
create_table :choices_questions, :id => false do |t|
t.references :choice, :question
t.timestamps
end
end
def self.down
drop_table :choices_questions
end
end
Let's check that we have no problems so far with a:
rake db:migrate
Next, we edit our models:
We say:
# question.rb
class Question < ActiveRecord::Base
has_and_belongs_to_many :choices
end
# choice.rb
class Choice < ActiveRecord::Base
has_and_belongs_to_many :questions
end
# questions_choice.rb
class QuestionsChoice < ActiveRecord::Base
belongs_to :question
belongs_to :choice
end
As a result, we should be able to access the table "Questions" from the table "Choices", and vice versa. "belongs_to", "has_and_belongs_to_many" are method calls of ActiveRecord. In a sense, Ruby let defines us our own domain-specific language easily, and that is basically what Rails is.
To show that the models are working, it is helpful to check with the Ruby interpreter first. For this, we start:
./survey/ > script/console -s
The -s option says we want to use a sandbox, i.e. our modifications in the database are rollbacked after we exit from the console.
So, first
q = Question.new
q.whatabout="Our Rails tutorial"
q.save
gives us a first question where we can add choices to. We do this with
c = Choice.new(:desc => "it's ok")
q.choices << c
Ruby knows from our models how to set the foreign key question_id and choice_id in the join table by using the operator "<<". We can repeat editing and adding new choices for our first question database.
Within the console, we can list all our choices for a question with:
q.choices.each {|choice| puts "#{choice.id} #{choice.desc}"}
In the next part of the tutorial, we will have a look on how we can provide a user interface for our models on questions and choices
No comments:
Post a Comment