użycie modułów w aplikacji

Zamieszczam poniżej kod modułu, kod kontrolera i “Full Trace”

[code=ruby]module NestedTree
#przesuwa obiekt do góry
def up(table, o, o2)
width = o.right - o.left + 1
new_width = o2.right - o2.left + 1
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” * (-1) WHERE “right” BETWEEN #{o.left} AND #{o.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” * (-1) WHERE “left” BETWEEN #{o.left} AND #{o.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” + #{width} WHERE “right” BETWEEN #{o2.left} AND #{o2.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” + #{width} WHERE “left” BETWEEN #{o2.left} AND #{o2.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” + #{new_width} WHERE “right” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” + #{new_width} WHERE “left” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” * (-1) WHERE “right” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” * (-1) WHERE “left” < 0”)
end

def up_translation(table, o, o2, language_id)
width = o.right - o.left + 1
new_width = o2.right - o2.left + 1
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” * (-1) WHERE “language_id” = #{language_id} and (“right” BETWEEN #{o.left} AND #{o.right})”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” * (-1) WHERE “language_id” = #{language_id} and (“left” BETWEEN #{o.left} AND #{o.right})”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” + #{width} WHERE “language_id” = #{language_id} and (“right” BETWEEN #{o.left} AND #{o.right})”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” + #{width} WHERE “language_id” = #{language_id} and (“left” BETWEEN #{o.left} AND #{o.right})”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” + #{new_width} WHERE “language_id” = #{language_id} and “right” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” + #{new_width} WHERE “language_id” = #{language_id} and “left” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” * (-1) WHERE “language_id” = #{language_id} and “right” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” * (-1) WHERE “language_id” = #{language_id} and “left” < 0”)
end

#przesuwa obiekt w dół
def down(table, o, o2)
width = o.right - o.left + 1
new_width = o2.right - o2.left + 1
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” * (-1) WHERE “right” BETWEEN #{o.left} AND #{o.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” * (-1) WHERE “left” BETWEEN #{o.left} AND #{o.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” - #{width} WHERE “right” BETWEEN #{o2.left} AND #{o2.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” - #{width} WHERE “left” BETWEEN #{o2.left} AND #{o2.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” - #{new_width} WHERE “right” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” - #{new_width} WHERE “left” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” * (-1) WHERE “right” < 0”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” * (-1) WHERE “left” < 0”)
end

#przygotowuje obiekt do dodania nowego wierzchołka
def add(table, o)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “right” = “right” + 2 WHERE “right” >= #{o.right}”)
ActiveRecord::Base.connection.update(“UPDATE #{table} SET “left” = “left” + 2 WHERE “left” > #{o.right}”)
end
end[/code]

[code=ruby]require ‘nested_tree’

class Admin::UnitsController < ApplicationController
include NestedTree

#przenosi oddział w górę, na tym samym poziomie
def move_up
o = Unit.find :first, :include => :unit_translations, :conditions => [‘unit_translations.language_id = ? and units.id = ?’, @current_language.id, params[:id]]
o2 = Unit.find :first, :include => :unit_translations, :conditions => [‘unit_translations.language_id = ? and unit_translations.right = ? and units.level = ?’, @current_language.id, o.unit_translations[0].left - 1, o.level] unless o.nil?
UnitTranslation.transaction do
NestedTree.up_translation(“unit_translations”, o.unit_translations[0], o2.unit_translations[0], @current_language.id) if !(o.nil?) && !(o2.nil?) && o.level == o2.level
end
redirect_to :action => ‘index’, :locale => I18n.locale
end
end[/code]

app/controllers/admin/units_controller.rb:184:in `block in move_up' activerecord (3.0.3) lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction' activerecord (3.0.3) lib/active_record/transactions.rb:204:in `transaction' app/controllers/admin/units_controller.rb:182:in `move_up' actionpack (3.0.3) lib/action_controller/metal/implicit_render.rb:4:in `send_action' actionpack (3.0.3) lib/abstract_controller/base.rb:151:in `process_action' actionpack (3.0.3) lib/action_controller/metal/rendering.rb:11:in `process_action' actionpack (3.0.3) lib/abstract_controller/callbacks.rb:18:in `block in process_action' activesupport (3.0.3) lib/active_support/callbacks.rb:445:in `_run__816774191__process_action__718303440__callbacks' activesupport (3.0.3) lib/active_support/callbacks.rb:409:in `_run_process_action_callbacks' activesupport (3.0.3) lib/active_support/callbacks.rb:93:in `run_callbacks' actionpack (3.0.3) lib/abstract_controller/callbacks.rb:17:in `process_action' actionpack (3.0.3) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action' activesupport (3.0.3) lib/active_support/notifications.rb:52:in `block in instrument' activesupport (3.0.3) lib/active_support/notifications/instrumenter.rb:21:in `instrument' activesupport (3.0.3) lib/active_support/notifications.rb:52:in `instrument' actionpack (3.0.3) lib/action_controller/metal/instrumentation.rb:29:in `process_action' actionpack (3.0.3) lib/action_controller/metal/rescue.rb:17:in `process_action' actionpack (3.0.3) lib/abstract_controller/base.rb:120:in `process' actionpack (3.0.3) lib/abstract_controller/rendering.rb:40:in `process' actionpack (3.0.3) lib/action_controller/metal.rb:138:in `dispatch' actionpack (3.0.3) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch' actionpack (3.0.3) lib/action_controller/metal.rb:178:in `block in action' actionpack (3.0.3) lib/action_dispatch/routing/route_set.rb:62:in `call' actionpack (3.0.3) lib/action_dispatch/routing/route_set.rb:62:in `dispatch' actionpack (3.0.3) lib/action_dispatch/routing/route_set.rb:27:in `call' rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in `block in call' rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in `block in recognize' rack-mount (0.6.14) lib/rack/mount/code_generation.rb:131:in `optimized_each' rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in `recognize' rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in `call' actionpack (3.0.3) lib/action_dispatch/routing/route_set.rb:492:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/head.rb:14:in `call' rack (1.2.2) lib/rack/methodoverride.rb:24:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/params_parser.rb:21:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/flash.rb:182:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/cookies.rb:295:in `call' activerecord (3.0.3) lib/active_record/query_cache.rb:32:in `block in call' activerecord (3.0.3) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache' activerecord (3.0.3) lib/active_record/query_cache.rb:12:in `cache' activerecord (3.0.3) lib/active_record/query_cache.rb:31:in `call' activerecord (3.0.3) lib/active_record/connection_adapters/abstract/connection_pool.rb:353:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/callbacks.rb:46:in `block in call' activesupport (3.0.3) lib/active_support/callbacks.rb:415:in `_run_call_callbacks' actionpack (3.0.3) lib/action_dispatch/middleware/callbacks.rb:44:in `call' rack (1.2.2) lib/rack/sendfile.rb:107:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/remote_ip.rb:48:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/show_exceptions.rb:46:in `call' railties (3.0.3) lib/rails/rack/logger.rb:13:in `call' rack (1.2.2) lib/rack/runtime.rb:17:in `call' activesupport (3.0.3) lib/active_support/cache/strategy/local_cache.rb:72:in `call' rack (1.2.2) lib/rack/lock.rb:11:in `block in call' <internal:prelude>:10:in `synchronize' rack (1.2.2) lib/rack/lock.rb:11:in `call' actionpack (3.0.3) lib/action_dispatch/middleware/static.rb:30:in `call' railties (3.0.3) lib/rails/application.rb:168:in `call' railties (3.0.3) lib/rails/application.rb:77:in `method_missing' railties (3.0.3) lib/rails/rack/log_tailer.rb:14:in `call' rack (1.2.2) lib/rack/content_length.rb:13:in `call' rack (1.2.2) lib/rack/handler/webrick.rb:52:in `service' /home/wafcio/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service' /home/wafcio/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run' /home/wafcio/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'
EDIT:

Znalazłem rozwiązanie chodziaż to mi się troche dziwne wydaje. Po zainncludowaniu NestedTree powinienem jak wywołuje up_translation to wchodzi mi do tej funkcji i ją znajduje bez problemu, ale z przedrostkiem ‘NestedTree.’ to już nie działa, dziwne.

Jezu…

wiem teraz przepisze to przy uzyciu awesome_nested_set, co znacznie zmniejszy kod i zrobi go bardziej przejrzystym. Ale problem skorzystania z modułu dalej pozostanie nierozwiązany.

Jak przeczytasz jak działa ruby i kiedy używasz modułów do tworzenia przestrzeni nazw a, kiedy do współdzielenia funkcjonalności to będzie dla ciebie jasne

Ok mamy święta, to można wytłumaczyć kilka rzeczy, które są we wstępie do rubiego w większości książek :slight_smile:

Moduły są też nazywane/pełnią rolę tzw. mixin’ów. Ruby nie obsługuje wielodziedziczenia, ale za pomocą includowania modułów do danej klasy można w niej mieć dostęp do metod zdefiniowanych w tymże module. Dlatego wywołujesz funkcję bez przedrostka NestedTree, bo “wmieszałeś” go do swojej klasy i jego metody stały się metodami twojej klasy/obiektu tej klasy. Wywoływałbyś z przedrostkiem, gdybyś nie includował, przy samym require.

BTW Czy mi się tylko wydaje, czy od jakiejś wersji rails’y wczytują automatycznie wszystko z /lib? Czy może już nie?

Od wersji 3 już nie wczytują

O Boże, i właśnie dlatego Ci napisałem, że masz pisać bez przedrostka nazwy modułu. :S

ActiveRecord::Base.connection.update("UPDATE #{table} SET \"right\" = \"right\" * (-1) WHERE \"right\" BETWEEN #{o.left} AND #{o.right}") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"left\" = \"left\" * (-1) WHERE \"left\" BETWEEN #{o.left} AND #{o.right}") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"right\" = \"right\" + #{width} WHERE \"right\" BETWEEN #{o2.left} AND #{o2.right}") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"left\" = \"left\" + #{width} WHERE \"left\" BETWEEN #{o2.left} AND #{o2.right}") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"right\" = \"right\" + #{new_width} WHERE \"right\" < 0") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"left\" = \"left\" + #{new_width} WHERE \"left\" < 0") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"right\" = \"right\" * (-1) WHERE \"right\" < 0") ActiveRecord::Base.connection.update("UPDATE #{table} SET \"left\" = \"left\" * (-1) WHERE \"left\" < 0")
Aplikacja będzie o wiele wydajniejsza jeśli wrzucisz te zapytania bezpośrednio do plików ERB.

To jakiś słaby żart którego nie rozumiem?

Weź go tak brutalnie nie troluj – jeśli pisze taki kod, to jest gotów potraktować Twoją radę zupełnie poważnie.

Ja tylko chciałem przypomnieć, że każdy kiedyś zaczyna. Chyba, że wasz kod ociekał zajebistością już od pierwszej linijki.

No właśnie. Dlatego fajnie by było, gdyby Nairda zamiast trolowania pozwolił Wafciowi dać szansę jakiemuś gemowi do zagnieżdżonych zbiorów.

[quote=gotar]module Test
def self.test

end
end

include Test
Test.test

działa dla mnie[/quote]
Ten include jest zbędny. Moje doświadczenie mówi, że większość programistów Rubiego nie wie do końca co robi include i kiedy go się powinno używać (oraz tego, że include w globalnym zasięgu jest zły).