bitrix_on_rails 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -4,10 +4,11 @@ source "http://rubygems.org"
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
6
  gem 'rails', ">= 3.0"
7
+ gem 'php_serialize', :git => 'git://github.com/dapi/php_serialize.git'
7
8
 
8
9
  # Add dependencies to develop your gem here.
9
10
  # Include everything needed to run rake, tests, features, etc.
10
- group :development do
11
+ group :development, :test do
11
12
  gem "sqlite3"
12
13
  gem "shoulda", ">= 0"
13
14
  gem "bundler", "~> 1.0.0"
@@ -15,6 +16,8 @@ group :development do
15
16
  gem "rcov", ">= 0"
16
17
  gem "ruby-debug19", :require=>'ruby-debug'
17
18
 
19
+ gem 'factory_girl'
20
+
18
21
  gem 'test-unit'
19
22
 
20
23
  gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
data/Gemfile.lock CHANGED
@@ -1,3 +1,9 @@
1
+ GIT
2
+ remote: git://github.com/dapi/php_serialize.git
3
+ revision: e7ebc71561d2210481de52e1227fdb4bdb1a39d6
4
+ specs:
5
+ php_serialize (1.2)
6
+
1
7
  GEM
2
8
  remote: http://rubygems.org/
3
9
  specs:
@@ -34,8 +40,8 @@ GEM
34
40
  columnize (0.3.4)
35
41
  erubis (2.6.6)
36
42
  abstract (>= 1.0.0)
43
+ factory_girl (2.0.2)
37
44
  git (1.2.5)
38
- growl (1.0.3)
39
45
  guard (0.5.1)
40
46
  thor (~> 0.14.6)
41
47
  guard-test (0.3.0)
@@ -75,7 +81,6 @@ GEM
75
81
  rdoc (~> 3.4)
76
82
  thor (~> 0.14.4)
77
83
  rake (0.9.2)
78
- rb-fsevent (0.4.2)
79
84
  rcov (0.9.9)
80
85
  rdoc (3.9.1)
81
86
  rr (1.0.3)
@@ -106,11 +111,11 @@ PLATFORMS
106
111
 
107
112
  DEPENDENCIES
108
113
  bundler (~> 1.0.0)
109
- growl
114
+ factory_girl
110
115
  guard-test
111
116
  jeweler (~> 1.6.4)
117
+ php_serialize!
112
118
  rails (>= 3.0)
113
- rb-fsevent
114
119
  rcov
115
120
  ruby-debug19
116
121
  shoulda
data/Guardfile CHANGED
@@ -6,6 +6,7 @@ guard 'test' do
6
6
  watch(%r{^test/.+_test\.rb$})
7
7
  watch(%r{^test/test_.+\.rb$})
8
8
  watch('test/helper.rb') { "test" }
9
+ watch('test/factories.rb') { "test" }
9
10
 
10
11
  # Rails example
11
12
  watch(%r{^app/models/(.+)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" }
data/README.rdoc CHANGED
@@ -23,6 +23,12 @@ prop_s - для одиночных свойтсв, prop_m - для множес
23
23
 
24
24
  === Инфоблоки
25
25
 
26
+ Для создания модели элемента инфоблока:
27
+ - наследуем модель от IblockElement
28
+ - в конце файла добавляем BitrixOnRails.send :create_iblock_class, _номер_инфоблока_, _имя_модели_ unless Rails.application.config.cache_classes
29
+ - в config/initializers/bitrix_on_rails.rb в блок BitrixOnRails.configure добавляем c.infoblock _номер_инфоблока_, :extended_class => _имя_модели_
30
+ Далее работаем с инфоблоком, как с обычной моделью.
31
+
26
32
  1. Все модели для таблиц b_iblock_*
27
33
  2. Автоматическая установка свойств из таблиц prop_s*/prop_m* в методы объекта IblockElement.
28
34
  Например IblockElement.find(1).name_emittents, где name_emittent - свойство из prop_s.
@@ -112,13 +118,13 @@ prop_s - для одиночных свойтсв, prop_m - для множес
112
118
  encoding: cp1251
113
119
  ...
114
120
 
115
- == Тестирование
121
+ == Тесты
116
122
 
117
123
  bundle exec guard
118
124
 
119
125
  или
120
126
 
121
- rake test
127
+ bundle exec rake test
122
128
 
123
129
  == TODO
124
130
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.8
1
+ 0.2.0
data/app/models/iblock.rb CHANGED
@@ -84,21 +84,10 @@ class Iblock < ActiveRecord::Base
84
84
  scope.send eval_method, "def #{code}=(value); property_set.send('#{code}=', value); end"
85
85
  end
86
86
  scope.send eval_method, "def property_#{code}=(value); property_set.send('#{code}=', value); end"
87
-
88
- # Если мы спрашиваем iblock_element.post
89
- # то он ищет ключ :post_id в свойствах элемента
90
- # и если находит, то возвращает Post.find_by_id(properties[:post_id])
91
- # if code.to_s=~/_id$/
92
- # method = code.to_s.gsub(/_id$/,'')
93
- # if Kernel.const_defined? class_name = code.to_s.humanize
94
- # instance_eval "def #{method}; #{class_name}.find_by_id(self.send :#{code}); end"
95
- # end
96
- # end
97
87
  }
98
88
 
99
89
  end
100
-
101
- end
90
+ end # self
102
91
 
103
92
  def to_s
104
93
  name
@@ -111,34 +100,4 @@ class Iblock < ActiveRecord::Base
111
100
  def property_codes
112
101
  self.class.get_property_codes(id)
113
102
  end
114
-
115
- def init_property_models
116
- return unless version==2
117
- iblock_id = self.id
118
-
119
- # Создаем классы IblockElementPropSНОМЕР
120
- #
121
- const_name = "IblockElementPropS#{iblock_id}"
122
- unless Kernel.const_defined? const_name
123
- e = Class.new(ActiveRecord::Base) do
124
- extend BitrixOnRails::IblockElementPropS
125
- acts_as_iblock_element_prop_s(iblock_id)
126
- end
127
- Kernel.const_set const_name, e
128
- end
129
- Kernel.const_get(const_name).init
130
-
131
- # Создаем классы IblockElementPropMНОМЕР
132
- #
133
- const_name = "IblockElementPropM#{iblock_id}"
134
- unless Kernel.const_defined? const_name
135
- e = Class.new(ActiveRecord::Base) do
136
- extend BitrixOnRails::IblockElementPropM
137
- acts_as_iblock_element_prop_m(iblock_id)
138
- end
139
- Kernel.const_set "IblockElementPropM#{iblock_id}", e
140
- end
141
- Kernel.const_get(const_name).init
142
- end
143
-
144
103
  end
@@ -1,11 +1,30 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  class IblockElement < ActiveRecord::Base
3
+
4
+ class << self
5
+ # Хранит id инфоблока, с которым связан класс. Устанавливается для классов
6
+ # наследуемых от IblockElement.
7
+ @iblock_id = nil
8
+
9
+ # Хранит хеш свойств, хранящихся в IblockElementPropS*. Устанавливается для
10
+ # классов наследуемых от IblockElement.
11
+ @iblock_properties = nil
12
+
13
+ def iblock_id
14
+ @iblock_id
15
+ end
16
+
17
+ def iblock_properties
18
+ @iblock_properties
19
+ end
20
+ end
21
+
3
22
  set_table_name :b_iblock_element
4
23
 
5
24
  belongs_to :iblock
6
25
  belongs_to :iblock_section
7
26
 
8
- after_find { Iblock.define_delegated_methods(self, self.iblock_id) }
27
+ # after_find { Iblock.define_delegated_methods(self, self.iblock_id) }
9
28
 
10
29
  # Применяется только для iblock-ов 1-й версии
11
30
  #
@@ -16,42 +35,7 @@ class IblockElement < ActiveRecord::Base
16
35
  has_many :iblock_section_elements
17
36
  has_many :iblock_sections, :through => :iblock_section_elements
18
37
 
19
- class << self
20
- def iblock_id
21
- @iblock_id
22
- end
23
-
24
- def property_codes
25
- raise "Не установлен @iblock_id" unless iblock_id
26
- Iblock.get_property_codes(iblock_id)
27
- end
28
-
29
- def set_iblock_id(id)
30
- @iblock_id = id
31
-
32
- hash = {
33
- :class_name => Iblock.s_props_class(id).name,
34
- :foreign_key => 'iblock_element_id',
35
- :autosave => true}
36
- has_one :s_prop, hash
37
- has_one "iblock_element_prop_s#{iblock_id}".to_sym, hash
38
-
39
- has_many :m_prop_values, :class_name => Iblock.m_props_class(id),
40
- :foreign_key => 'iblock_element_id', :autosave => true
41
-
42
- default_scope where(:iblock_id => id, :active => 'Y')
43
-
44
- property_codes.each { |code, number|
45
- define_method(code) do
46
- property_set.send(code)
47
- end
48
-
49
- define_method("#{code}=") do |value|
50
- property_set.send("#{code}=", value)
51
- end
52
- }
53
- end
54
- end
38
+ default_scope where(:active => 'Y')
55
39
 
56
40
  def property_codes
57
41
  ::Iblock.get_property_codes(self.iblock_id)
@@ -60,12 +44,4 @@ class IblockElement < ActiveRecord::Base
60
44
  def to_s
61
45
  name
62
46
  end
63
-
64
- def multiply_properties
65
- send "iblock_element_prop_m#{iblock_id}"
66
- end
67
-
68
- def property_set
69
- send "iblock_element_prop_s#{iblock_id}"
70
- end
71
47
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bitrix_on_rails}
8
- s.version = "0.1.8"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Danil Pismenny"]
12
- s.date = %q{2011-08-04}
11
+ s.authors = [%q{Danil Pismenny}]
12
+ s.date = %q{2011-08-29}
13
13
  s.description = %q{Использование инфоблоков 1С-Битрикс в Ruby On Rails проектах}
14
14
  s.email = %q{danil@orionet.ru}
15
15
  s.extra_rdoc_files = [
@@ -40,19 +40,25 @@ Gem::Specification.new do |s|
40
40
  "lib/active_record/connection_adapters/mysql2_downcase_adapter.rb",
41
41
  "lib/bitrix_on_rails.rb",
42
42
  "lib/bitrix_on_rails/active_record.rb",
43
+ "lib/bitrix_on_rails/configuration.rb",
43
44
  "lib/bitrix_on_rails/engine.rb",
45
+ "lib/bitrix_on_rails/iblock_element.rb",
44
46
  "lib/bitrix_on_rails/iblock_element_prop_m.rb",
45
47
  "lib/bitrix_on_rails/iblock_element_prop_s.rb",
46
48
  "test/dump.sql",
49
+ "test/factories.rb",
47
50
  "test/get_dump.sh",
48
51
  "test/helper.rb",
49
52
  "test/schema.rb",
50
- "test/test_bitrix_on_rails.rb"
53
+ "test/test_active_record.rb",
54
+ "test/test_bitrix_on_rails.rb",
55
+ "test/test_iblock_element.rb",
56
+ "test/test_iblock_element_prop_s.rb"
51
57
  ]
52
58
  s.homepage = %q{http://github.com/dapi/bitrix_on_rails}
53
- s.licenses = ["MIT"]
54
- s.require_paths = ["lib"]
55
- s.rubygems_version = %q{1.6.2}
59
+ s.licenses = [%q{MIT}]
60
+ s.require_paths = [%q{lib}]
61
+ s.rubygems_version = %q{1.8.6}
56
62
  s.summary = %q{Работа с инфоблоками 1С-Битрикс}
57
63
 
58
64
  if s.respond_to? :specification_version then
@@ -60,42 +66,42 @@ Gem::Specification.new do |s|
60
66
 
61
67
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
62
68
  s.add_runtime_dependency(%q<rails>, [">= 3.0"])
69
+ s.add_runtime_dependency(%q<php_serialize>, [">= 0"])
63
70
  s.add_development_dependency(%q<sqlite3>, [">= 0"])
64
71
  s.add_development_dependency(%q<shoulda>, [">= 0"])
65
72
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
66
73
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
67
74
  s.add_development_dependency(%q<rcov>, [">= 0"])
68
75
  s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
76
+ s.add_development_dependency(%q<factory_girl>, [">= 0"])
69
77
  s.add_development_dependency(%q<test-unit>, [">= 0"])
70
- s.add_development_dependency(%q<rb-fsevent>, [">= 0"])
71
- s.add_development_dependency(%q<growl>, [">= 0"])
72
78
  s.add_development_dependency(%q<guard-test>, [">= 0"])
73
79
  s.add_development_dependency(%q<test-unit-rr>, [">= 0"])
74
80
  else
75
81
  s.add_dependency(%q<rails>, [">= 3.0"])
82
+ s.add_dependency(%q<php_serialize>, [">= 0"])
76
83
  s.add_dependency(%q<sqlite3>, [">= 0"])
77
84
  s.add_dependency(%q<shoulda>, [">= 0"])
78
85
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
79
86
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
80
87
  s.add_dependency(%q<rcov>, [">= 0"])
81
88
  s.add_dependency(%q<ruby-debug19>, [">= 0"])
89
+ s.add_dependency(%q<factory_girl>, [">= 0"])
82
90
  s.add_dependency(%q<test-unit>, [">= 0"])
83
- s.add_dependency(%q<rb-fsevent>, [">= 0"])
84
- s.add_dependency(%q<growl>, [">= 0"])
85
91
  s.add_dependency(%q<guard-test>, [">= 0"])
86
92
  s.add_dependency(%q<test-unit-rr>, [">= 0"])
87
93
  end
88
94
  else
89
95
  s.add_dependency(%q<rails>, [">= 3.0"])
96
+ s.add_dependency(%q<php_serialize>, [">= 0"])
90
97
  s.add_dependency(%q<sqlite3>, [">= 0"])
91
98
  s.add_dependency(%q<shoulda>, [">= 0"])
92
99
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
93
100
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
94
101
  s.add_dependency(%q<rcov>, [">= 0"])
95
102
  s.add_dependency(%q<ruby-debug19>, [">= 0"])
103
+ s.add_dependency(%q<factory_girl>, [">= 0"])
96
104
  s.add_dependency(%q<test-unit>, [">= 0"])
97
- s.add_dependency(%q<rb-fsevent>, [">= 0"])
98
- s.add_dependency(%q<growl>, [">= 0"])
99
105
  s.add_dependency(%q<guard-test>, [">= 0"])
100
106
  s.add_dependency(%q<test-unit-rr>, [">= 0"])
101
107
  end
@@ -1,19 +1,25 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'rails'
3
3
  require 'active_record'
4
+ require 'php_serialize'
4
5
 
5
6
  module BitrixOnRails
6
- def self.init
7
- # При работе с тестовой базой может случиться ситуация, что база пуста и никакой таблицы b_iblock
8
- # там нет, что приведет к ислючению. Проверка сделана для корректной работы Rake задач.
9
- if ::ActiveRecord::Base.connection.tables.include? 'b_iblock'
10
- Iblock.all.map &:init_property_models
11
- end
7
+ def self.configure
8
+ return unless ::ActiveRecord::Base.connection.tables.include? 'b_iblock'
9
+
10
+ config = Configuration.new
11
+ yield config
12
+
13
+ config.infoblocks.each { |infoblock|
14
+ BitrixOnRails.define_iblock_class(infoblock[:iblock_id], infoblock[:options])
15
+ }
12
16
  end
13
17
  end
14
18
 
15
19
  require 'bitrix_on_rails/engine'
20
+ require 'bitrix_on_rails/configuration'
16
21
  require 'bitrix_on_rails/active_record'
22
+ require 'bitrix_on_rails/iblock_element'
17
23
  require 'bitrix_on_rails/iblock_element_prop_s'
18
24
  require 'bitrix_on_rails/iblock_element_prop_m'
19
25
 
@@ -3,22 +3,30 @@
3
3
  module BitrixOnRails
4
4
  module ActiveRecord
5
5
 
6
- def has_infoblock(iblock_id, property_name, &blk)
6
+ # TODO: Добавить еще один параметр delegated_methods, через который пользователь сможет определить
7
+ # методы, которые необходимо проделегировать в iblock_element
8
+ def has_infoblock(iblock_id, foreign_key)
7
9
  prop_s_name = "iblock_element_prop_s#{iblock_id}".to_sym
8
- has_one prop_s_name, :foreign_key => property_name, :class_name => "::IblockElementPropS#{iblock_id}", :autosave => true
10
+ iblock_element_class = BitrixOnRails.infoblocks[iblock_id]
9
11
 
10
- element_class = Class.new IblockElement do
11
- set_iblock_id iblock_id
12
- end
13
- element_class.class_eval(&blk) if block_given?
12
+ has_one prop_s_name, :class_name => "::IblockElementPropS#{iblock_id}", :foreign_key => foreign_key , :autosave => true
13
+ full_class_name = self.name
14
+ class_name = full_class_name.split('::').last.underscore.to_sym
14
15
 
15
- self.const_set('Element', element_class)
16
+ Object.const_get("IblockElementPropS#{iblock_id}").instance_eval {
17
+ belongs_to class_name, :class_name => full_class_name, :foreign_key => foreign_key
18
+ }
16
19
 
17
- self.class_eval("def property_set; iblock_element.property_set; end")
18
- Iblock.define_delegated_methods(self, iblock_id, true)
19
-
20
- has_one :iblock_element, :through => prop_s_name, :class_name => 'Element', :autosave => true
20
+ has_one :iblock_element, :class_name => iblock_element_class.name, :through => prop_s_name
21
21
 
22
+ iblock_element_class.iblock_properties.each { |m, property|
23
+ # Во избежание коллизий не стоит делегировать методы вроде post_id, blog_id дальше
24
+ unless m.to_s =~ /_id$/ || self.columns.find{ |c| c.name == m.to_s}
25
+ delegate m, :to => :iblock_element
26
+ delegate "#{m}=", :to => :iblock_element unless property[:multiple]
27
+ end
28
+ }
22
29
  end
30
+
23
31
  end
24
32
  end
@@ -0,0 +1,26 @@
1
+ module BitrixOnRails
2
+ class Configuration
3
+ attr_reader :infoblocks
4
+
5
+ def initialize
6
+ @infoblocks = []
7
+ end
8
+
9
+ # Создание необходимой инфраструктуры для работы с инфоблоком, id которого равен iblock_id.
10
+ # Пользователь может задать следующие параметры через options:
11
+ #
12
+ # * :class_name - имя класса для создаваемого наследника от IblockElement. Если пользователь не задал
13
+ # эту опцию, а также не задал :extended_class, то новый класс будет называется IblockElement3, где 3 -
14
+ # iblock_id.
15
+ # * :extended_class - класс, который необходимо расширить (предполагается, что он наследуется от IblockElement).
16
+ # Эта опция имеет преимущество перед :class_name.
17
+ # * :extended_by - модуль, который будет включен в создаваемый класс.
18
+ #
19
+ def infoblock(iblock_id, options = {})
20
+ @infoblocks << {
21
+ :iblock_id => iblock_id,
22
+ :options => options
23
+ }
24
+ end
25
+ end
26
+ end