Nelze spustit server s Edge Rails

Posted by Jan Kubr Mon, 28 May 2007 18:07:00 GMT

Pokud žijete "on the edge" a po instalaci Edge Rails vám nejde spustit ani Mongrel, ani Webrick s více či méně návodnými chybovými hláškami, zkuste:

sudo gem install activeresource --source http://gems.rubyonrails.org

Mělo by pomoci.

Posted in | no comments |

Implementace OpenID

Posted by Jan Kubr Wed, 25 Apr 2007 20:17:00 GMT

Obecné povídání o OpenID si můžete přečíst např. ode mě na Flempu nebo od Arthura Denta hned na několika místech. Tady bych rád připsal pár tipů pro implementaci autentikace pomocí OpenID ve vaší Rails aplikaci.

Jak se dalo čekat, i na OpenID existuje plugin. Jeho použití však nebylo tak snadné, jak jsem čekal. Pár poznámek vám snad ušetří problémy, na které jsem narazil já.

Za prvé, plugin vyžaduje Edge Rails (někde to napsané je, u toho pluginu ale ne). Edge Rails zase vyžadují poslední verzi RubyGems, jinak vaše aplikace nebude fungovat. Dále, v příkladu použití pluginu je několik chyb, přečtěte si komentáře pod ním, bez popsaných úprav kód fungovat nebude.

Je nepravděpodobné, že byste chtěli použít přesně stejné metody jako jsou v příkladu (protože typicky už nějakou autentikaci v aplikaci máte, že). Při jejich modifikaci je dobré si pořádně rozmyslet, jak OpenID funguje. Je-li místo uživatelského jména a hesla zadáno OpenID (jak to zjistíte je specifické pro vaši aplikaci, já prostě jako OpenID chápu uživatelská jména začínající "http://"; podotýkám, že metoda této detekce je z příkladu u pluginu volána, její tělo ale uvedeno není), je řízení předáno metodě authenticate_with_open_id, která přesměruje prohlížeč na stránky poskytovatele OpenID, kde je uživatel požádán o zadání přístupových údajů. Tento server pak přesměruje uživatele zpět do vaší aplikace s informací, jak přihlášení dopadlo. Akci, do které je tento výsledek "doručen" specifikujete v routes.rb direktivou map.open_id_complete. Příklad u pluginu počítá s tím, že se vracíte do stejné metody jako při přihlašování. Zde je znovu zjištěno, je-li přihlašování prováděno pomocí OpenID a pokud ano, metoda authenticate_with_open_id už nikam nepřesměrovává, ale jen "vrátí" výsledek pokusu o příhlášení.

Problém je, že mi při druhém vstupu přihlašovací metody nebyly poslány parametry, které uživatel zadal do formuláře při přihlašování (s GET parametry to fungovalo dobře). Musel jsem si tedy tyto údaje uložit sám do session.

Doufám, že jsem alespoň někomu ušetřil pár hodin ladění a zkoumání.

Posted in | no comments |

Using instantiated fixtures with multiple database access

Posted by Robert Cigán Tue, 29 Aug 2006 08:03:00 GMT

V návaznosti na implementaci projektu používající vícenásobný databázaový přístup, jsem byl nucem vytvořit adekvátní testovací prostředí. Následující text je také uveden na http://wiki.rubyonrails.com/rails/pages/HowtoUseMultipleDatabasesWithFixtures

Using instantiated fixtures with multiple databases without modifying AR

RoR testing with instantiated fixtures while using multiple databases is more possible then ever. All you need to do is just implement your own test_helper method, that load fixtures into the databases and instatiate them. Here’s my code, which i use in my project(just copy it into test_helper.rb):

cattr_accessor :classes_cache
  #class cache for storing already founded classes from models
  @@classes_cache = {}

  def load_user_fixtures(*table_names)
    fixtures = {}
    table_names = table_names.flatten.collect{|t| t.to_s}
    table_names.each do |table_name|
      unless @@classes_cache[table_name].nil?
        klas = @@classes_cache[table_name]
      else
        begin 
          #try to find class name from table name
          klas = eval(table_name.classify)
        rescue
          #go to model directory, run through all models and search for table name
          classes = Dir.entries(RAILS_ROOT + "/app/models").select{|d| d.include?(".rb")}.collect{|f| File.basename(f, ".rb").classify}
          klas_names = classes.select{|f| (eval("#{f}.table_name") rescue false)==table_name }
          klas_name = klas_names.blank? ? table_name.classify : klas_names.first
          klas = eval(klas_name)
        end
        @@classes_cache[table_name] = klas
      end
      #load fixture
      fixtures[table_name] = Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures", table_name, 
                                                      {table_name.to_sym => klas.name}){klas.connection}
    end
    #run through all fixtures and instantiate them
    fixtures.each_pair do |table_name, fixs|
      Fixtures.instantiate_fixtures(self, table_name, fixs)
    end
  end
Disable transactional and instantiated fixtures

self.use_transactional_fixtures = false
self.use_instantiated_fixtures  = false
To load your fixtures in tests use implemented helper method in your unit or functional tests like this(notice, that load_user_fixtures is instance method, but regular fixtures method is class method)

require File.dirname(__FILE__) + '/../test_helper'

class EmployeeTest < Test::Unit::TestCase
  def setup
    load_user_fixtures :employees, :users
  end 
end

AR has a small bug when asking for table_name to class, which is inherited from abstract class. So we have to set table names even if they are the same as model name.

First set abstract class as usual to define connection.

  class AnotherDatabaseConnector < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "another_database_#{RAILS_ENV}" 
  # all subclasses use connection from here
end
All your subclasses accessing another database will look like this. We have to set table name for those, inherited from our abstract class.

class User < AnotherDatabaseConnector
  set_table_name "users" # we need to set this explicitly
end
I done this, because i had many tests already done, and i was too lazy to rewrite them for non-instantiated fixtures, and it works, you don’t have to change anything in AR, you don’t have to set DB connections in tests, all you have to do is just use this method to load fixtures instead of default method fixtures.

If you have any problems or suggestions, you can discuss email me robert.cigan@skvely.cz, or chat directly using ICQ 82645774

- rimmer

Posted in | no comments |

AR::Base.establish_connection a MySQL connection lost

Posted by Robert Cigán Mon, 14 Aug 2006 11:14:00 GMT

V případě, že používáte ve Vaší aplikaci příkaz establish_connection, či jinak manipulujete s databázovým spojením v MySQL, může se Vám vyskytnout tato chyba. Vzniká relativně náhodně, sám jsem nebyl schopen určit, co je toho příčinou. Dle zahraničních blogů a fór jsem se dopátral řešení, a tím je update MySQL driveru pro ruby pomocí gem install mysql

Posted in | no comments |

SQL Decimal Support plugin

Posted by Robert Cigán Thu, 03 Aug 2006 11:33:04 GMT

Při implementaci aplikace, která pracuje s peněžními hodnotami jsem byl postaven před problém formátu pro ukládání. Po vyzkoušení několika různých způsobů jsem došel k závěru, že takto opravdu nelze. Přitom vývojová verze Rails má již implementovánu nativní podporu decimal typu v databázi s konverzí na BigDecimal třídu ruby (pevná řádová čárka).

Objevil jsem tento plugin - http://www.ashleymoran.me.uk/sqldecimalsupport.tgz - který dodává podporu typu decimal do SQL adaptérů a to jak pro migraci, tak pro konverzi při ukládání a získávání dat z DB.

Jelikož Rails On The Edge obsahují také v balíčku ActiveSupport::CoreExtensions potřebné konverze, tyto jsem k tomuto pluginu dodal a nyní jej používám ke své plné spokojenosti. Již nemusím vytvářet dodatečné getter a setter metody, či používat agregační objekty, nebo nedejbože starat se o chyby v plovoucí řádové čárce při práci s typem Float. Vše funguje tak jak má a jak již mělo fungovat dávno, kdyby na tuto, podle mě základní věc, vývojáři mysleli.

Plugin originálně převzat od Ashley Moran, http://www.ashleymoran.me.uk/sqldecimalsupport.tgz

Posted in | no comments |

Older posts: 1 2