Monday, March 31, 2014

Git pull tips

My project team is using Git (Open Source software) as a version control system to handle all the changes we made in the code. This software, combined with Bitbucket, a free code-hosting service, makes a really powerful tool which makes life easier (at least the programmer's life).

When we want to pull all the changes from the remote repository, we use the general pattern for the "pull" command:

> git pull [options] [<repository> [<refspec>...]]

The "standard" way to pull the remote repository is by typing:
> git pull

This fetches and integrates the remote repository with your local repository or local branch. However, a stashing operation before pulling is strongly recommended in order to avoid merge conflicts with not-done work (code tasks in progress). Git documentation defines the stashing operation as the one that "takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time." Then, we should type:

> git stash
> git pull

After these two consecutive operations, we can easily check if there exists something to be merged by using the "status" command:

> git status
If the pulling operation was successful, the console will show a message "no things need to be merged", otherwise, it will display an "unmerged" message, and you will have to decide what changes you want to keep by editing each one of the files listed. When all the files are merged (check it by typing again "git status" command), we would have our local repository already updated. Although it is also recommended to run two more commands:

> bundle install

Bundle install all the dependencies you need (gems from your specified sources). This is interesting to avoid issues if somebody changed any code in the Gemfile from the remote repository.
Finally, other useful way to keep the consistence of our application is related to possible migrations, so do not forget to run:

> rake db:migrate

This will run any migration stored in the /db/migrate/ folder. 

In my next post, I am going to talk about how to pull an specific folder when using Git.

Saturday, March 29, 2014

Fifth client meeting reactions

Yesterday, we met with professor Ackley in our fifth client meeting. We kept in mind the last time we tried to show a demo to Ackley (third client meeting), when we were not able to show the model properly because of a clear lack of preparation. Fortunately, we learnt from our mistakes and the past week we showed a decent demo to Nikan. As Ackley had not seen any proper demo, it was our chance to demonstrate that we had already most of functionality working.

As usual, we started the meeting with the last week task report. No problems in this sense, because all the members of the team were able to complete their tasks due to before the client meeting. Then, we spent almost all the rest of the meeting showing the demo. Last time, we used my laptop to present our demo. It actually worked fine, but since I am running Rails on an Ubuntu installation inside a Virtual Machine (VirtualBox), the screen resolution features are not as good as in a regular installation. This caused some minor visualization issues when we ran the demo using Firefox browser. Therefore, this time we decided to use Natalie's Macbook laptop in order to avoid this kind of problems that could worsen the user's experience.

Again, the Demigod's demo was really good because we were able to show all the functionality that were working properly so far. As we were working most of the time focused on the functionality rather than on the design, the demo looked not as pretty as we liked, but the main goal right now is that the application works fine, and then, we will address the style and design stuff.

Even though we did a great job showing the demo, Ackley made some comments about our application, such as:

- The Index page may include a kind of animated carousel.
- Profile page: show the user’s name instead of the email. Include the username and a logout button on the right side of the navigation bar, as usual on this kind of websites.
- A small picture of each challenge may be added. Also applied for the different categories of challenges.
- He suggested using always the same name to define a "Check-in", instead of things like “Success”.
- Fail button should include a confirmation dialog (“Are you sure?”)
- What the points really mean? Points distribution: Can you distribute the points in different dimensions?
- Statistics and challenges page need better design...
- On the way encouragement when you log in (motivation quotes or something similar)
- Decide the final list of challenges.
- Was the maximum number of check-ins per week (7) our choice?
- He also suggest starting to think about the final demo of our project.

However, it seems Ackley liked our demo, and he said that his less concern about our project so far is about the functionality. This sounded like "Ok guys, let's focus on the design", but we still have to deal with some functionality features. Anyway, we are going to start working on the design the next week.

Wednesday, March 26, 2014

Guest speaker in class

Last Monday,  the founder of Vandyke Software visited our class and talked to us about how software is developing in the real world. He explained that every day, they follow the same pattern when we work on a software project:

- Feature requests, bug reports
  • Test track (database)
    • Acceptance tests (light-weight process. No database needed. It includes conversations between developers and project managers)
      • Iteration planning (Poker estimates, 1 hour/day in average)
        • Story, stories (Theme)
          • Task estimates (developers & project managers)
            • Buffer (Were the estimates good enough?)
            • Fudge factor (Measure how good were the estimates)
- Iteration
  • Bootlog Friday (Relieve value)
- Commit (Smaller code chunks are usually better)
- QA (If the code does not pass the tests, send back to developers as soon as possible)

He spoke about the iteration planning, focusing on the Poker estimates. They are basically a way to estimate the effort needed to achieve a goal when working on a software project (how long this task/problem will take?). If there is not a clear idea about the the task duration estimate, it is a good idea to divide the problem is smaller problems, because they will definitely be easier to measure. In terms on task estimates, he said that developers can only make rough estimates, but project managers are able to do more accurate estimates because they have the project's budget. Anyway, it is always better for all the members of the team to divide tasks in smaller chunks in order to estimate times, although the average task duration should be between 4 and 8 hours.

Moreover, from the point of view of Vandyke, the stories based on a theme (basically a request that has been already received previously) should be splitted (again the same approach) into two or three weeks in order to get something more valuable at the end. He also talked to us about code committing and the difference between his expectation and the reality, because, ideally, developers should commit code ready to be submitted, however, about the 50% of the committed code comes back to developers after being tested by QA. Regarding how to commit the code. Vandyke explained that sometimes is very difficult for developers to commit small code portions, but they should try to do it, because if a bug comes up, it will be easier and faster for the rest of the team to find out where the issue is.

He also referred several times to a book named "Extreme programming explained: embrace change", which he recommended for all the developers interested in software engineering.

Monday, March 24, 2014

Generating a new scaffold in Rails

Recently, Natalie and I had other programming session in which we decided to create a new structure in order to get an easier way to deal with the check-ins interval. This had to be done by splitting the challenge's duration in weeks (instead of considering the whole duration) to keep track of the check-ins made by the user.

We essentially required to create a new Rails model that actually could be directly generated through the Rails console. But instead of using that method, we decided to setup up a scaffold, a tool provided by Rails which helps programmers create structures such as views, models and controllers for a new resource, but only in a single operation. In this case, we had to create a new model, so thanks to the scaffolding method, we were able to do it easily by using the following pattern :

rails g model <model_name> <field_1:type> <field_2:type> … <field_n:type>

The previous command generates a new table in the database with the specified fields and data types. In our case, the model was called "week", and it contained three fields:

rails g model week start_week:datetime end_week:datetime checkins_completed:boolean

Rails console creates the migration file in /db/migrate/ folder, by labeling it with the common patter: <current_date>_create_<model_name>.rb. Rails also executes this migration in our repository, thus, Rails creates the model itself (weeks.rb) in the ./project_name/app/models/ folder, as well as the rspec file (spec/models/week_spec.rb) and the factory file (spec/factories/weeks.rb)

Once we had the new table, we added the current data from other tables (relations) into the new table by following this convention (creating a new migration file):

rails g migration Add<source_field_name1>And<source_field_name2>And<source_field_name_n>To<destination_table> <destination_field_name1>:<type> <destination_field_name2>:<type> ...<destination_field_name_n>:<type>

Note that you need to apply the previous code separately for each one of the tables you want to get any field.

For example, we created two migration files, one per each table of the database we dealt with:

rails g migration AddUserIdAndUserChallengeIdAndCheckinsToWeek user_id:integer user_challenge_id:integer checkins:integer

rails g migration AddWeekIdToHistory week_id:integer

We edited the generated migration files adding the proper information to the new table. For example, this was the code for the Week table:

create_table "weeks", force: true do |t|
t.datetime "start_week"
t.datetime "end_week"
t.boolean "checkins_completed"
t.datetime "created_at"
t.datetime "updated_at"
t.string "user_id"
t.integer "user_challenge_id"
end

Finally, Natalie and I added the active record associations (in our particular case, "belongs_to" and "has_many" associations) into the model files (history.rb and week.rb), and we executed a rake db:migrate command in order to apply all the changes in our local repositories.

Sunday, March 23, 2014

Migrations in Ruby on Rails

Last week, Natalie and I continued working on the progress bar. In order to keep track of the challenges that the user have succeed, we decided that we need to add a new field to the database. This new boolean field had to be added to the user challenges table, and was called "finished". We looked for some documentation, and we figured out that there was a kind of migration "convention", which is used each time you want to make changes in a database.

The first step was to create the new column in the database by typing in the RoR console (Rails c) a command that follows this pattern:

rails g migration add_<new_field_name>_to_<table_name> <new_field_name>:<type>

If we need to delete a column, we should use the same format, but switching "add" by "remove":

rails g migration remove_<field_name>_from_<table_name>

Returning to our particular case, the command used was:

rails g migration add_finished_to_user_challenges finished:boolean

This command creates a new .rb file in the migrations folder, located at your_project_folder/db/migrate/. It is labeled with the current date following by the same name as we wrote the previous command. For this reason, it is very important to use the convention that I commented on the first paragraph.

Thus, we edited the new migration file, by creating a new class that generates the new field:

class AddFinishedToUserChallenge < ActiveRecord::Migration
  def change
    add_column :user_challenges, :finished, :boolean, default: false
  end
end

Moreover, we also decided to edit an existing field in the same table (user_challenges) and the histories table. This time, we needed to change the data type of the "duration" field, because it was created as an integer. As it was calculated by multiplying the number of times per week that the user have to check in and the number of weeks of the challenge, and we divided that value by 100 to get a progress bar percentage, the value was eventually rounded causing accuracy issues. Therefore, Natalie and I changed the "duration" field type from integer to decimal, following this format:

rails g migration change_data_type_for_<field_name>_in_<table_name>

Applying the previous pattern to our case:

rails g migration change_data_type_for_progress_in_user_challenges

rails g migration change_data_type_for_progress_in_histories

After creating the migration files, the next step was to define the class in both files to define the migrations:

class ChangeDataTypeForProgressInUserChallenge < ActiveRecord::Migration
  def change
    change_table :user_challenges do |t|
      t.change :progress, :decimal
    end
  end
end

Finally, Natalie and I executed a rake db:migrate command to apply the changes specified in the migration files. Thanks to this approach, we committed all the new files and the rest of the members of the team were able to pull this files, getting the same changes immediately.

- More information about migrations on RoR

Thursday, March 20, 2014

Fourth client meeting reactions

We had our fourth client meeting last Friday with Nikan, as we are switching our client (Nikan <-> Ackley) every week. This time, there was a new way for us to face a meeting, because we had to plan the agenda of the meeting. All the points to discuss were up to us.

At the beginning, it may seemed as a benefit for the team, because you can actually divide the time (25 minutes) as you want, focusing on the parts you prefer to discuss or showing a demo to your client. You actually take the control over the meeting, and you are able to choose the points that you want to deal with. This way may be seen as an advantage, but sometimes it could be tricky especially if you do not distribute your time correctly, because you have to be able to control the meeting's flow by distributing the time. Hence, if you want to success, keep in mind that you need to plan the meeting in advance, and then, fit your meeting's agenda as you planned.

For this reason, we decided discussing about the schedule before Friday's meeting. As we had certain parts of the functionality already running, we decided focus the meeting on showing Nikan a model with the progress since we start working: user registration and sign in process, avatar upload, challenge selection page, current challenge progress bar (I have been working on it with Natalie for several weeks), new challenges creation, etc.

Although we wanted to spend most of the time available showing the demo, we began the meeting with a brief review over the tasks done the previous week. In the meantime, we have fulfilled the timeline and all the weekly tasks have completed by each team member. After that, we went through the Demigod demo. Note that in the last meeting we made a mistake when we tried to show a demo to Ackley, but fortunately we learned from our mistakes, and this time we brought a laptop with a Rails server running and the website ready to be displayed.

The demo was introduced by Matt, who clearly explained each functionality which was already working properly as well as showed several suggestions and tests suggested by Nikan. We felt that she was really satisfied with our work, and she actually congratulated us for our progress. Moreover, I think we made a great control of the time, because once we ended the demo we still had five minutes left to identified the tasks we need to accomplish due next meeting (after the Spring Break).

From my point of view, this was the most successful client meeting so far. We hope the next one be even better since we are working hard to have all the Demigod's functionality ready as soon as possible.

Monday, March 17, 2014

Demigod: How to avoid cheating when check-in using jQuery and Ruby

Natalie and I have worked on the challenges progress bar. The number of check-ins needed to success the challenge depends on two variables whose combination gives its duration (or number of total check-ins needed): the number of check-ins per week, and the number of weeks. So, if we select a challenge requires 2 check-ins per week during 4 weeks, the duration is going to be 8 check-ins. Taken into account the previous statement, the main problem is how to control user's cheating when check-in, because if we do not control it, a user could check-in continuously, succeeding the challenge in few seconds.

The idea was to simplify the problem and then, trying to apply to a real situation. To do this in a simple approach, we thought that the easiest way was to prevent check-ins in the first minute since the user picks a challenge. We needed to disable the "Success" and "Fail" buttons during one minute, and then, enable both of them. We focused on the user's challenge partial file, one of the files we have in the views/users/ folder (Ruby on Rails).

The first variable we need is the current progress for the selected challenge, which we retrieved from the instance variable in the users controller (*.rb). Note that we added Ruby code inside the jQuery function using the proper syntax: #{ruby_code}:

var progress = #{@current_progress};

We created a new function called isValidCheckin which receives the current progress and basically checks the time that has passed since the first time stamp in the database associated to that pair challenge-user (we use an history table to store this information). Therefore, the function either enables or disables the "Success"/"Fail buttons depending on the time time between the first time stamp and the current time. Because of testing reasons, we set this time to 1 minute delay:

    function isValidCheckin(progress){
          
        var startTimestamp = "#{@start_timestamp}";
        var difference = "#{(Time.now - @start_timestamp.to_time)/1.minute}";
        console.log("Difference: " + difference);
        
        if(difference > 1 && progress < 100){
          $('#successBtn').removeAttr("disabled");
          $('#failBtn').removeAttr("disabled");
        }
        else {
          $('#successBtn').attr("disabled","disabled");
          $('#failBtn').attr("disabled","disabled");
        } 

    } 

To get the number of minutes that have passed since the first time stamp, Ruby has a very useful function: number.minute/day/hour/year... In this case, we used 1.minute, that gets the number of minutes. Having this value stored in the "difference" variable, we checked if it is greater than 1 minute, and if the challenge is not completed yet, we enabled both buttons, otherwise, we disabled them.

Natalie and I started by initializing the buttons, because the user could refresh the page or even log out and log in again. Anyway, if the current challenge is not started yet (progress = 0) or it is done (progress = 100), we had to avoid check-in by disabling both buttons with the "attr" jQuery property. Else, if the challenge is in progress, the buttons must be enabled (jQuery property "removeAttr"):

if ((progress >= 100) || (progress == 0)){
        $('#successBtn').attr("disabled","disabled");
        $('#failBtn').attr("disabled","disabled");
      }
      else if (progress > 0 && progress < 100){
        //enable buttons
        $('#successBtn').removeAttr("disabled");
        $('#failBtn').removeAttr("disabled");
      }

After this piece of code, we called the function to check the time:

isValidCheckin(Progress);

We also added some "breakpoints" to check the variable values on the browser's console. This can be easily done by writing the console.log(variable_name), for example:

console.log("Challenge progress: " + progress);
console.log("Difference (min): " + difference);

In order to test the code, we picked a random challenge and then, we checked the Firefox's console, that showed these messages:

As the challenge was not started, the progress is 0, and the difference en minutes since the challenge started was just a few seconds., the outcome showed on our browser was a disabled "Success" button:


1 minute after we picked the challenge, we refreshed the browser, and again, we checked the console:


Now, the difference is more than 1 minute, so we were able to check in:


The next step is to convert this code to do the same function when the minimum time needed to wait between check-ins depends on the challenge's duration, as I told in the first paragraph.

Saturday, March 15, 2014

User experience: influencing customer decisions

In the last lecture, we discussed about the user experience (UX). According to Wikipedia, it involves a person's behaviors, attitudes, and emotions about using a particular product, system or service. The last three words of this definition mean that UX is not only applied to software development, but also to any product. Anyway, we are going to focus on this term from the point of view of software engineering.

Based on my previous experience as a freelance web designer, I had the opportunity of dealing with several customers and different projects. In general, I noticed that most of the customers get carried away by my recommendations, especially in terms of design and style (always respecting the corporate identity). It is very important to identify as quick as possible if our clients have a clear idea about what they want when you face a software project. It requires attention to detail, and some experience in client meetings. Furthermore, you also need to display strong communications skills, because most of the UX is not so much about applying the right methodologies or being an outstanding designer, it is more about properly communication with your customer. Regarding this fact, I think that the main goal is to know how to persuade or influence your client in some way that involves taking significant decisions or making changes based on your own recommendations. It may sound "unethical", but is the way followed by many UX engineers  (whenever possible) to get the best results, and I can confirm that it works with most of the customers. It seems like they feel more confident when they get advice from a professional who is used to work/design similar things (such as a website, software, hardware, etc).

In addition, it is always a good practice letting external users be part of the project somehow. They should be familiar with the technology you are working on, but only in terms on usability if possible. This practice is widely used during the test stage (also called "beta testers"), but I think that external users can collaborate with the project almost from the beginning. For example, they may give their point of view about the story board (design stage), because they actually do not need experience or skills in software development. Following this approach you can get quick benefits based on their UX, because it is very common that designers and programmers overlook certain mistakes or improvements that could be easily fixed. That is the reason why a "third party point of view" may be so interesting particularly in software development.

Wednesday, March 12, 2014

Midterm self-evaluation: areas for improvement

Despite we did not have to post our midterm self-evaluation, I would like to write some lines about one of the most interesting parts of this assignment. I have never in my life done a self-evaluation for an University course, but after writing the document, I feel like it could be very helpful for both the professor and the student, because you have to go through over all your achievements, homework, assignments, things you did better or worse, etc. For this reason, I believe that the outcome is an evaluation that you can use to realize what were your strongest points, as well as your weakness, in other words, areas that need improvement.

Regarding these areas, in my case I will need to improve the following ones:

- Speaking: This is my main challenge for the rest of the semester. As an exchange student, I often have problems to understand the discussions in class as well as with my project team, but I will try to improve and put more attention. Moreover, I believe that one of the mistakes of my proposal was related to my pitch, especially in the questions time. I actually did not feel confident when I tried to give a proper answer to my classmate's questions, and this was definitely reflected to the audience in a lack of believability. From my point of view, I lost a lot of points on this part of my pitch.

- Participation: This is mostly related to the previous area. Honestly, I did not participate as frequently as I would like, but I will try to do it by increasing my participation in both meetings (client and team) and class discussions, giving my point of view every time I have the chance.

- Coding skills: I acknowledge that I do not have strong skills in programming (in general). Additionally, I had to learn new languages in order to face the Demigod project. In the mean time, I am glad with the team decision of using Ruby on Rails, but it also implies using other languages such as jQuery, Haml, CSS, etc. A lot of new things to learn in such a short time, that is the problem. Nowadays, I am doing a great effort to understand how they work, but it is not easy for me. Anyway, I am attempting to contribute to my project as much as I can, but I have to improve my skills on these programming languages.

Monday, March 10, 2014

Third client meeting reactions

Last Friday, we had our third client meeting, this time with professor Ackley. As in the previous sessions, the first part of the meeting was addressed to review the assigned tasks made by each member of the team. During the third week of the project, I was working with Natalie on the current challenge progress bar. We decided to meet together last Wednesday (two days before the client meeting) and we spent four hours trying to find a way to update the bar dynamically using jQuery when a user clicks on the "Success" button. We also made some tests to try the avatar uploading system, because we wanted that the picture was cropped if it was bigger than certain resolution. Despite having several problems, we finally got it, and we were able to obtain something that worked properly with random values, enough to be shown in the client meeting if it was needed.

In the next part of the meeting, our team needed to prove somehow that the key technology choice for Demigod project by using the Goldilocks method. In this case, we justified that Ruby on Rails was the best option to develop our website. Fortunately, it was quick and clear. Too much: Java or PHP (Great flexibility but would have taken too long to build up an entire), too little: Open Source Content Management Systems such as Wordpress, Joomla! or Drupal (easy to use, but the platform would not have been useful for creating a customized website), just right: Ruby on Rails (nice middle ground between customization and automatic generation).

Furthermore, we provide explanations about how certain parts of the application worked (progress bar, challenge selection and follow up, etc.). From my point of view, we made a mistake when professor Ackley wanted to see some of the parts of the website that was already working. We tried to run the website, but the time was limited and we finally were not able to show the model properly because of lack of preparation for this part of the meeting. Next time, we have to bring a laptop with the rails server running and all ready to be shown. Time is very important in a meeting, and we (and mostly our client) cannot afford to waste such a valuable time trying to set up the website. I hope we do not make this kind of mistakes any more.

Additionally, it seemed we were lack of confidence when Ackley asked us questions such as "What happens if you are doing a challenge and you forgot to check in?" We also turned in the final version of the timeline, as well as a list with possible challenges and the Goldilocks method outlines. Finally, following the timeline, we reported the tasks appointed to each member due the fourth week.

Friday, March 7, 2014

Gitg: Git client for Linux

In my last post, I wrote about the way to update our local repository from Bitbucket using the Ubuntu command line.I was working through the Ubuntu terminal, downloading the project from the Bitbucket's repository and I have not had any problem so far. It works fine and it is actually not  a big deal.

However, what happens when you are a Linux user and you want to upload some changes made in your computer (local repository) to the Bitbucket's repository? I made a quick research, and I quickly realized that there is a wide number of graphical Git clients for Linux. According to the reviews and opinions found on the Internet, I firstly installed Giggle, which seemed to be the most simple option. Despite you are able to view the changes that you have previously committed, you cannot either commit your changes nor pull/push operations, so I finally uninstalled it.

Gitg screenshot

Then, I tried other option recommended in several forums: Gitg. It has a design as simple as Giggle, but by using Gitg, you are able to commit changes and view the repositories with a friendly and colorful graphical display which makes easier to see all the changes. Installing Gitg on Ubuntu is really simple. You just have to run this command (you need superuser permissions):

$ sudo apt-get install gitg

The first step is to configure your online repository. This can be done through the File menu -> Repository properties, adding the URL there. To commit the changes, you need to select the "Commit" label on the top bar, which shows the files you changed on your local repository ("Unstage" box). By right clicking on each one of them (also available multiple selection), you have to click on the "Stage" option (prepare selected files finely for a commit) in the contextual menu. After this step, the files you want to commit will disappear from the "Unstage" box, passing to the "Stage" box. You can also add a commit message explaining the changes you made on the files committed. This is particularly useful to keep track of all the modifications, as well as inform and explain your teammates those changes. The last step in Gitg is to click on "Commit" button, that logically runs the commit operation.

In fact, there is only one step left. You have to push the changes in order to upload them to Bitbucket (or your preferred online repository). The easiest way to accomplished this operation is using the Terminal, but before run the appropriate command, you need to find out what is your alias (configurable by the command git config) and your branch (typically "master").

$ git push [alias] [branch]

Once you push the changes, you can check on Bitbucket if all worked fine by verifying the last commit's list.

Wednesday, March 5, 2014

Second team meeting: Updating repositories & redefining the timeline

Last Sunday, our team held the second meeting. It seems like the weekends are the most suitable time to meet together, because of work, class schedule, and so on.

The first task we accomplished was to update our local repositories to the last version of the project. We are using Bitbucket, a free web service for hosting projects with Git revision control systems. I did not know this application, but after two weeks working on the project, I can say that it is a very useful web tool when you are part of a work team. Despite existing a commercial version, the free account is enough to develop small projects with a limited number of team members (up to five users).

Depending on your Operating System, it is easier or harder to find a software to download and commit the changes made in the project. In my case, I am running Ubuntu 12.04 x86, and there exists some applications to do these kind of tasks. However, after checking some forums, I noticed that most of people prefer to update their local repositories using the command line. When I need to update my code with the last version hosted in Bitbucket, I take the following steps:

Open the Terminal and go to your project's root directory, then:
$ git stash -> Stashes all of your local changes temporarily.
$ git pull -> Pulls all of the source code from the repository.
$ git status -> Lists the status of the code downloaded. If the output shows files needed to be merged (which you will know because there is a section called "unmerged"), then you will need to open all of the files in that section. The changes upstream (top half) is the stuff pulled from the repository. The code under the "======" symbols is related to the changes you made, and you have to decide what part stays and what goes, deleting the rest of the code. Besides, yo need to get rid of "=====" and "<<<< >>>" stuff. After merges are fixed, you have to run:
$ git reset HEAD + the full path for each of the files you worked on as an argument. 

If you are luck and there is nothing to merge, you can skip the previous steps and write the last two commands. These are very important after a pull, just in case other team member added something to the Gemfile or a migration :

$ bundle install -> Install the dependencies specified in your local Gemfile.
$ rake db:migrate -> Download the last version of the database

Moreover, we redefined the timeline of the project (this was one of the Nikan's requests in the last client meeting), in other words, we created a more accurate and detailed version (actually, it is a Google Doc) by adding the specific tasks for each member during each one of the weeks left. Now, it is more clear, and I am quite sure about we are able to fulfill the schedule.

For the current week, I was assigned to continue working with Natalie in the progress bar module. We need to figure out how to change it dynamically when the user clicks on the "success" button. This should be done by using some jQuery function, but I have never in my life programmed jQuery, so I will need to find information and probably some tutorials on the Internet. Besides, we have to decide a pattern for the classes and id's of the style sheets (CSS) in order to follow the same format when we write code. Finally, we are going to prepare the next client meeting (this Friday), because we have to justify somehow the key technology choice (basically Ruby on Rails) made by this project.

Monday, March 3, 2014

CSS and Ruby on Rails

After a week working on Demigod project, I acknowledge that it is actually more interesting than I expected at the beginning. One of the Ruby on Rails features that I like the most was the way Haml (HTML Abstraction Markup Language) pages connect with CSS style sheets. I am used to write code in HTML, which syntax is well-known among programmers. Thus, once you want to declare a new DIV structure, and associate it with CSS styles, you should write something like this:

<div class='wrap'>
    <div class='right'>
        //HTML code
    </div>
    <div class='left'>
        //HTML code
    </div>
</div>

And create the new classes in your CSS file (let's call it: mystyle.css), for example:

.left {
    background-color: yellow;
    overflow: hidden;
    margin-top: 20px;
    width:25%;
}

.right {
    background-color: red;
    float: right;
    width: 95%;
}

Additionally, you need to specify in your HTML file thename of the CSS file (in this case: <link rel="stylesheet" type="text/css" href="mystyle.css"> . Fortunately, things are much easier with Ruby on Rails, because both the DIV and the associated class take the same identification, and the DIV tag does not need to be closed. So, the above code in HTML becomes the following one in Haml:

.wrap
   .right
    -# Haml code
  .left
    -# Haml code

Easier and cleaner! I also tested this feature using id's instead of classes (i.e. #left instead of .left in the style sheet), and it worked properly. Despite RoR uses SCSS files (Syntactically Awesome Stylesheets), the syntax is the same as the classic CSS. It only requires to set the same name to both the style sheet and the haml file where the style is utilized.Furthermore, you have to to leave the SCSS file in an specific directory:

project_name\app\assets\stylesheets\haml_page_name.css.scss

Finally, I would like to say just one general thing to take into account when programming in Ruby on Rails. In my case, more than 80% of the compilation errors came from code indentation issues. From my point of view, the easiest way to indent the code with no errors is to use always the tab key and avoid using the space key, because I quickly noticed RoR is especially indentation-sensitive.