Screencast #2. Darome rounded corners mygtukus

Posted by Fiodor Vereščiaka 27/04/2008 at 22h31

Ši karta papasakosiu vieną greitą būdą kaip galima sukurti rounded corners mygtuką, kuris vienodai veiks Firefox, Opera, Safari, IE6 ir IE7 naršyklėse.

<table style="border-collapse: collapse;">
  <tr>
    <td style="background: url(/images/button_left.png) no-repeat 0 0; width: 12px; height: 38px;">
    </td>
    <td style="background: url(/images/button_middle.png) repeat-x 0 0; height: 38px; color: white; font-weight: bold;">
      Paspausk Mane!
    </td>
    <td style="background: url(/images/button_right.png) no-repeat 0 0; width: 12px; height: 38px;">
    </td>
  </tr>
</table>

O gal Jūs žinote koki kitą gera būda, būtų labai įdomų sužinoti. Geriausio sprendimo autorius gaus šokoladinį kiškį ;) !

Įdomaus ir naudingo žiūrėjimo: rounded_corners

Posted in  | 12 comments | no trackbacks

Screencast #1. Rails 2.1 naujovė - "named scopes"

Posted by Saulius Grigaitis 16/04/2008 at 22h28

Su džiaugsmu pristatau pirmąjį screencast’ą, kurį sukūrė Fiodor Vereščiaka. Fiodor pasakoja apie vieną iš būsimų Rails 2.1 naujovių – named scopes. Tai išties patogus funkcionalumas, kuris iki šiol buvo atskirame įskiepyje HasFinder.
class User < ActiveRecord::Base
  named_scope :active, :conditions => { :active => true }
  named_scope :male, :conditions => { :gender => 'm' }
  named_scope :female, :conditions => { :gender => 'f' }
end

Tada galime patogiai išrinkti:

User.active.female

Įdomaus ir naudingo žiūrėjimo: named_scopes

Posted in  | 6 comments | no trackbacks

Forumas ir Screencast'ai !

Posted by Saulius Grigaitis 16/04/2008 at 20h57

Dauguma šio tinklapio lankytojų jau pastebėjo atsiradusią nuorodą į forumą. Forumas buvo pristatytas RubyConfLT 1.2008 konferencijos metu, o nuo šiol jis oficialiai atidarytas, tad visi galite diskuoti su Ruby susijusiomis temomis. Be to, atidarome ir screencast’ų skiltį, kurioje talpinsime mūsų sukurtus ir įrašytus screencast’us Ruby tematika. Pirmąjį screencast’ą sukūrė Fiodor Vereščiaka apie vieną iš naujovių Ruby on Rails 2.1 versijos karkase – named scopes. Įdomaus ir naudingo žiūrėjimo!

4 comments | no trackbacks

RubyConfLT 1.2008 įspūdžiai

Posted by Saulius Grigaitis 14/04/2008 at 21h13

Buvo išties “fun” :). Buvo džiugu matyti nemažai entuziastų, kurie aktyviai dalyvavo visą konferencijos laiką, nors pranešimai truko net iki 21-os valandos. Nors tai RubyConf, konferencijos metu daugiausia kalbėta ne vien apie Ruby, bet ir apie Rails, Merb bei Chuck Noriss :). Visą tai artimiausiu metu galėsite pamatyti ir konferencijos vaizdo įrašuose, kurie bus patalpinti KTU distancinių mokymų centro tinklapyje. Dėkui Artūrui už konferencijos organizavimą, pranešėjams, publikai, KTU DMC darbuotojams ir visiems kitiems, prisidėjusiems prie šios konferencijos. Tikiuosi, netruks ilgai iki sekančio susitikimo.

Konferencijos akimirkos:;




RubyConfLT 1.2008

Ir pranešimų skaidrės:

  • Artūras Šlajus:
  • Eimantas Vaičiūnas:
  • Saulius Grigaitis:
  • Fiodor Vereščiaka:
  • Laurynas Liutkus:
  • 3 comments | no trackbacks

    RubyConfLT 1.2008

    Posted by Saulius Grigaitis 29/03/2008 at 17h42

    Daugelyje šalių rengiamos “RubyConf” konferencijos susilaukė didelio susidomėjimo tiek profesionalių “Ruby” programuotojų, tiek pradedančiųjų tarpe.

    KTU rengiamo kasmetinio “InfoShow” festivalio metu pirmą kartą vyks “RubyConfLT” konferencija, kuri taip pat išlaikys “RubyConf” konferencijų koncepsiją, bet bus daugiau orientuota į pradedančiuosius “Ruby” ir “Ruby on Rails” programuotojus. Konferencijos metu bus aptariamos tiek ekspertams, tiek ir pradedantiesiems aktualios temos:

    • Artūras ‘arturaz’ Šlajus

      • How I fell in love (and started abusing) Ruby
      • Rails? Čia tas naujas serialas iš Meksikos?
      • (Į)skiepai nuo galvasopio
      • Pažintis su CRUD-oriented architektūros kūrimu
      • Rails profilingas ir optimizavimas
    • Eimantas ‘enc’ Vaičiūnas

      • UJS: nepiktas HTML tiuningas su unobtrusive Javascript
    • Saulius Grigaitis

      • Testavimas su RSpec/Selenium/Watir
      • Saugus seksas su Rails
      • Rails “deploy’inimas” lengvai
    • Fiodor Vereščiaka

      • MERB: WEB’as su Ruby tai ne tik Rails (+ data_mapper)

    Susitiksime RubyConfLT 1.2008 !

    Daugiau informacijos: arturaz.net/blog/rubyconflt-12008/

    no comments | no trackbacks

    Pavasaris!

    Posted by Saulius Grigaitis 29/03/2008 at 16h58

    Pagaliau išsikraustėm iš hostingo, kuriame negana to, kad downtime’as buvo didesnis už uptime’ą, dar ir neaiškiomis aplinkybėmis dingo duomenys ne tik iš duomenų bazės, bet ir iš atsarginės kopijos. Laimei, straipsnius pavyko atkurti iš kešuotos HTML versijos, o straipsnių komentarai dar laukia savo eilės. Taip pat atnaujinome ir pačią blog’inimo sistemą bei apvilkome pavasarinį rūbą.
    Šiek tiek keičiasi ir pačio tinklapio www.rubyonrails.lt koncepsija, daugiau dėmesio skirsime Lietuvos Ruby ir Rails bendruomenei. Straipsniai, kurie aktualūs tik Lietuvos Ruby ir Rails bendruomenei, bus skelbiami lietuvių kalba, o plačiajai auditorijai aktualūs straipsniai dažniausiai bus skelbiami anglų kalba. Artimiausiu metu startuos forumas, skirtas diskusijoms Ruby ir Rails tematika, tad galima bus diskutuoti ir ieškoti problemų sprendimų įvairiomis temomis. Visi kas turite pasiūlymų ar patarimų tiek blog’o, tiek būsimo forumo klausimais, ar norite prisidėti prie šios bendruomenės, parašykite apie tai komentaruose!

    no comments | no trackbacks

    OpenWFEru: Workflow and Business Process Machine engine(Introduction)

    Posted by Saulius Grigaitis 24/01/2008 at 22h37

    Nowadays Rails applications are RESTful, so in most cases it avoids any complex workflow(except minor things like account registration). But sometimes workflow becomes important element in application, then the quick way is to use status field, which works well at simple situations. For example Invoice model has status field, which is one of ["new", "pending", "paid", "canceled"] or so. The problem here is that workflow is hardcoded in code. So invoices with status "new" appears in new invoices page, because that action use something like Invoice.find(:all, :conditions => {:status => "new"}), and the same situation is with other pages. Here workflow is hardcoded. One day business process changes and new status of invoice is added, then programmer needs to analyze the app's code, remember the workflow implementation and change a lot of code in tests and models/views/controllers... Usually this is non-effective and painful.

    Other issue - business analyst or customer provides the workflow schematics, then programmers use those. Constantly schematics or implementation of that worklow is changed, but usually synchronization between schematics and implementation is lost, because people make mistakes or are too lazy :).

    Is there any solution to easer control of workflow and avoid mentioned issues? Yes, serious people call it orchestration:). The main idea is to get workflow defined in some external resource, like XML file. Then even business analyst can easily change the workflow with help of IDE, which allows to edit the workflow files(for example jBPM Process Designer for JBoss jBPM). Workflow and business process machine engine OpenWFE has been ported to Ruby, so Ruby folks can use OpenWFEru. Unfortunately, I couldn't find any usable process designer for this engine, but usually it is not painful to write process definition by hand in XML or Ruby.

    There are few things that one must understand before using OpenWFEru: business processes, participants and workitems(or tasks, or tokens, or other name for the same thing).Business processes are defined via trees of expressions named process definitions. Participants are those workers, which starts to do something when get workitem. Participants can be mailer, so it sends email once it gets workitem, or web service client, so it communicates with server via API once it gets workitem, or block of Ruby code, so this code will be executed once it gets workitem, or any other allowed participant. And the most important Gotcha is workitem. Workitem itself doesn't contain any task, it's only token. But one can associate variables with this workitem, so one can pass important data from one participant to other, like the ":translator" participant pass the "translation" to ":reporter" participant in the example. So workitem is created and passed to first participant once business process is initiated, this workitem is passed to next participant according to process definition once first participant completes his task. In same way workitem is passed thought entire process and participants knows when to do their job.

    Here is the simple example, which is based on openwferu.rb. There is very simple workflow: sequence of three participants. First one is you, your task is to enter text in english. Once you complete it, the workitem with the "source_text" you entered will be passed to second participant - translator. Translator here is Ruby block again, which calls google translation service(thanks to rbabel). Once text is translated, it is attached to workitem, and workitem is passed to third participant - reporter. This is Ruby block again, it only prints the source text and translated text. As you see, it is very easy to change the translator. What you need to do, is only change the block of current translator, or register new participant and replace old participant's name in process definition with new one. Also, it is very easy to analyze and change workflow, you only need to be familar with XML(actually, workflow can be defined in Ruby too). And final thing is that participants are loosely coupled, the only one thing is the attached variables to workitem. So participants are like small units, which has input and output, so it's very easy to make various combinations of those units in complex sequences.

    #first install gems
    $ sudo gem install openwferu
    $ sudo gem install rbabel

    then execute this Ruby script

    
    require 'rubygems'
    require 'openwfe/def'
    require 'openwfe/workitem'
    require 'openwfe/engine/engine'
    require 'openwfe/participants/enoparticipants'
    require 'rbabel'
    
    # instantiating an engine
    
    engine = OpenWFE::Engine.new
    
    # adding some participants
    
    engine.register_participant :you do |workitem|
      puts "========================================="
      puts "Task for You" 
      puts "Please, enter text in english" 
      workitem.source_text = gets
      puts "========================================="
    end
    
    engine.register_participant :translator do |workitem|
      puts "==============Task for translator========"
      puts "translating text..."
      workitem.translation = workitem.source_text.translate(:en, :fr)
      puts "translated!"
      puts "========================================="
    end
    
    engine.register_participant :reporter do |workitem|
      puts "==============Task for reporter=========="
      puts "Text in english:\n#{workitem.source_text}\ntranslated to text in french: \n#{workitem.translation}"
      puts "========================================="
    end
    
    # a process definition
    definition =  
    '<process-definition revision="1" name="example">
      <sequence>
        <participant ref="you"></participant>
    
        <participant ref="translator"></participant>
        <participant ref="reporter"></participant>     
      </sequence>
    </process-definition>'
    
    # launching the process
    
    li = OpenWFE::LaunchItem.new(definition)
    
    li.initial_comment = "please give your impressions about http://ruby-lang.org"
    
    fei = engine.launch li
    
    # 'fei' means FlowExpressionId, the fei returned here is the
    # identifier for the root expression of the newly launched process
    
    puts "started process '#{fei.workflow_instance_id}'"
    engine.wait_for fei
    

     

    Yes, this example is very simple, but that was my way to show you this concept. If you understand the advantage of workflow and business process engine, then you can imagine how easy it is to implement complex workflow in dynamic enterprise, which is usually very painful without such engine.

    4 comments | no trackbacks

    (R)Spec for JavaScript

    Posted by Laurynas Liutkus 01/01/2008 at 22h39

    With the new year comes a new hope for You, JavaScript developer! Have you ever wanted to test whether your function calls AJAX properly? Or some Effect? Now you can. Just set up JsUnit, download spec.js, include it into your test html and try this:

    function testAjax() {
      expect_create(Ajax.Request).with_params(['/my/url', {asynchronous: true, evalScripts: true, parameters: {a: 'b'}}]);
    
      new Ajax.Request('/my/url', {asynchronous: true, evalScripts: true, parameters: {a: 'b'}});
    }

    While this snippet looks quite nice (except for square brackets - I haven't decided whether to remove them or not), it still needs something. Setup and teardown - JSUnit runs setUp before and tearDown after every test.

    function setUp() {
      RSpec.setUp();
    }
    
    function tearDown() {
      RSpec.tearDown();
    }

    What was actually tested in the first snippet, was class creation with specified parameters. But what if you have an object with some very complex method and only need to be sure it is called. You don't care what will it do. Let's go!

    // let's create a class
    var Ship = Class.create({
      shoot = function(target) {
        alert('shooting specified target');
        new Ajax.Request(...);
      }
    });
    
    // add testing methods for instances of Ship
    Ship.addMethods(RSpecMethods);
    
    // now our test
    function testAttack() {
      ship = new Ship();
      ship.should_receive('shoot').with_params(['Deathstar']);
    
      //replace following line with simulated click event or something similar
      ship.shoot('Deathstar');
    }
    Got crazy? Don't specify any params, but specify how many times to expect:
    ship.should_receive('shoot').exactly(5);
    
    ship.shoot('Deathstar');
    ship.shoot('Norad II');
    ship.shoot('Moon');
    ship.shoot('Deathstar');
    ship.shoot('params', 'count', 'is', {not: 'checked'});

    2 comments | no trackbacks

    Rails plugins/engines: Loading files in development mode with "require_dependency"

    Posted by Saulius Grigaitis 22/11/2007 at 22h36

    The situation we discussed in pixel.lt blog post is interesting and some of you may have such situation. The guy introduced view of reusable components - rails engines. The main idea is to develop initial engine and then develop new engines, which extends the initial engine. Then develop more engines, which extends previous engines, then.... extend/change behavior of classes in main application. The issue is that files in plugins are not reloaded on each request in development mode, so the classes will be loaded only from main application after first request. To solve this problem just require the file paths of last engine in main application files with "require_dependency". So if you have model Car in engine A, then Car class is extended in engine B, and then class is extended in RAILS_ROOT/app/models, you need require path to Car file on engine B with "require_dependency" in the RAILS_ROOT/app/models/car.rb.

    no comments | no trackbacks

    Netbeans 6 - best IDE for Ruby and Rails?

    Posted by Saulius Grigaitis 26/09/2007 at 22h35

    I've tried Netbeans 6 with Ruby support yesterday. I'm impressed. I'm impressed twice:). I used Netbeans for programming tasks at the university few years ago, but Netbeans was just IDE for Java development, I never thought that they achieved so much in Ruby and Rails support nowadays. First of all, read what Infrid writes on his blog lifeonrails.org. There are some videos on netbeans.org too. That's impressive. Is it time to throw out your favorite IDE or editor even if it is textmate? In most cases - Yes.

    Unfortunately, there is no Netbeans precompiled binary or port for my favorite operating system FreeBSD, the same situation is with Java Application Server - GlassFish, which is suitable for deploying JRuby on Rails projects. If you do not use Linux, OS X, Solaris or Windows, then building Netbeans and GlassFish from source is probably the only one way to get it working in your box. This way should work for most of Unix derived operating systems, which has JDK 1.5 and other required tools like ANT. The instructions how to built Netbeans from source is available at Netbeans Wiki. Full Netbeans source code checkout and build takes about few hours if your machine and internet downstream are pretty fast, so be patient. The instructions how to build GlassFish ant the JAR archives are available at GlassFish Community. This JAR is suitable if you use FreeBSD. GlassFish is smaller, so the process takes less time than to build Netbeans.

    Great! So much new things comes to Ruby and Rails...

    no comments | no trackbacks