bitrix_on_rails 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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