Now, that the tables and models are setup, we implement the View and Controller layers. The scaffold has given already some start, but we'll change these to give our application a better survey character.
First, the index view of the questions. We want to see a simple list of questions that we have so far, and the associated choices.
So, let's edit this view in /survey/app/views/question/index.html.erb. We remove almost everything and replace it with a unlinked list in html like this:
Note how we have used a second unlinked list to display the choices that are associated with a question, and how the modify and destroy actions are removed to be accessible only from inside the question edit. The question can be edited by clicking on it.
At the moment, we don't have any choices yet in our database. Let's add some with putting "http://0.0.0.0:3000/choices" in the URL of our browser.
I add the following for now: "it's great", "much", "ok", "not much", "green", "blue", "red", "yellow"
Now, we arrive at one of the more difficult parts. Putting checkboxes in the new and edit views of the questions.
First, the new action in /survey/app/views/questions/new.html.erb :
We need to iterate over the choices. We can do this like this:
We also insert the loop in the edit view:
To have a short list in our show view on choices, we add in app/views/questions/show.html.erb:
So, that was part 2. By now, you should have a survey app where an administrator can easily enter questions and associate possible choices with these questions.
Next, we need to have users who can take part in the survey.
Welcome to my blog on thinking, software, design and intuition. I am collecting some thoughts here on thoughts I like.
Sunday, March 21, 2010
Saturday, March 20, 2010
doing a survey with ruby on rails (part 1)
This is a basic tutorial that might help you understand the basics of ruby-on-rails. The idea of the project comes from this stackoverflow.com question. My current rails working environment is 2.3.5.
As with every rails project, in the beginning rails gives you a basic project setup using the model-view-controller pattern.
Let's try:
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:
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".
With
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:
In the new migration, we add references to our "choices" and "questions" tables like this:
Let's check that we have no problems so far with a:
Next, we edit our models:
We say:
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:
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
gives us a first question where we can add choices to. We do this with
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:
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
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
Subscribe to:
Posts (Atom)