Не удается добавить пользовательский атрибут продукта через администратора
Я новичок в Spreecommerce и у меня возникают проблемы при создании продукта с пользовательским атрибутом delivery_on через интерфейс администратора. Короче говоря, я создаю миграцию product_decorator.rb, добавляю новый атрибут в разрешенные атрибуты, создаю файл защиты для страниц администратора. Тем не менее, я получаю сообщение об ошибке "Доставка не может быть пустым", когда я пытаюсь создать новый продукт через интерфейс администратора.
Заранее большое спасибо за любую помощь!
Я использую ruby 2.2.1, rails 4.2.3 и следующие гемы:
gem 'spree_core', branch: '3-0-stable'
gem 'spree_api', branch: '3-0-stable'
gem 'spree_backend', branch: '3-0-stable'
gem 'spree_gateway', github: 'spree/spree_gateway', branch: '3-0-stable'
gem 'devise'
Действия по воспроизведению
- Создать миграцию
rails g migration add_delivery_on_to_spree_products
В файле миграции YYYYMMDDHHMMSS_add_delivery_on_to_spree_products вставьте изменения в метод "change":
def change add_column :spree_products, :delivery_on, :date add_index :spree_products, :delivery_on end
- Бежать
bundle exec rake db:migrate
и добавляет атрибуты в таблицу spree_products, но не обновляет scheema.rb Бежать
rake db:migrate:reset
и он обновил схему. Но сначала он уничтожает БД. Не уверен, что это идеальный способ сделать это (следуя указаниям в этом потоке stackru)В папке app / models / spree создайте файл 'product_decorator.rb' и добавьте
Spree::Product.class_eval do validates :delivery_on, presence: true delegate_belongs_to :master, :delivery_on, :active end
В app/controllers/application_controllers.rb добавьте
Spree::PermittedAttributes.product_attributes << :delivery_on Spree::Api::ApiHelpers.product_attributes << :delivery_on
В app/overrides/spree создайте файл удаления "add_delivery_on_to_product_new":
Deface::Override.new(:virtual_path => 'spree/admin/products/new', :name => 'add_delivery_on_to_product_new', :original => '931806c52c232e6a373cb06fa739f3913ad13c3d', :insert_after => "erb[loud]:contains('text_field :available_on')", :text => " <%= f.field_container :delivery_on, class: ['form-group'] do %> <%= f.label :delivery_on, raw(Spree.t(:delivery_on) + content_tag(:span, ' *')) %> <%= f.error_message_on :delivery_on %> <%= f.text_field :delivery_on, :class => 'datepicker form-control' %> <% end %> ")
В app/overrides/spree создайте файл deface 'add_delivery_on_to_product_form':
Deface::Override.new(:virtual_path => 'spree/admin/products/_form', :name => 'add_delivery_on_to_product_edit', :original => '931806c52c232e6a373cb06fa739f3913ad13c3d', :insert_after => "erb[loud]:contains('text_field :available_on')", :text => " <%= f.field_container :delivery_on, class: ['form-group'] do %> <%= f.label :delivery_on, raw(Spree.t(:delivery_on) + content_tag(:span, ' *')) %> <%= f.error_message_on :delivery_on %> <%= f.text_field :delivery_on, :value => datepicker_field_value(@product.delivery_on), class: 'datepicker form-control' %> <% end %> ")
Перейдите по адресу localhost:3000/admin и попробуйте создать новый продукт, но я получаю сообщение об ошибке "Доставка не может быть пустой".
Вот вывод в логах
Запущено POST "/admin/products" для::1 в 2015-09-14 22:24:20 +0200 Обработка Spree::Admin::ProductsController# создать как параметры HTML: {"utf8"=>"✓", "authenticity_token"=>"O6BkeJEhquvCnu5nrIHwYYUZqkif8C9MqKRf4+qvjxH5UqkM9m+QDwvxcfBFqE4QcwPnDU/wrwAKGyk+wzVz8 =="> ">"> ">"> ">"> ">"> ">"> ">"", "price"=>"99", "available_on"=>"2015/09/12", "delivery_on"=>"2015/09/30", "shipping_category_id"=>"1"}, "button"=>""} Spree:: Предпочтительная загрузка (0,1 мс) ВЫБЕРИТЕ "spree_preferences".* FROM "spree_preferences" ГДЕ "spree_preferences". "Key" =? LIMIT 1 [["key", "spree/backend_configuration/locale"]] Загрузка пользователя (0,4 мс) ВЫБРАТЬ "users".* FROM "users" WHERE "users"."Id" =? ORDER BY "users"."Id" ASC LIMIT 1 [["id", 1]] (0,1 мс) SELECT COUNT(*) ОТ "spree_roles" INNER JOIN "spree_roles_users" ON "spree_roles"."Id" = "spree_roles_users"."role_id"ГДЕ"spree_roles_users"."user_id" =? И "spree_roles". "Name" =? [["user_id", 1], ["name", "admin"]] (0,2 мс) начать транзакцию Spree:: Продукт существует (1,1 мс) ВЫБЕРИТЕ 1 КАК ОТ "spree_products" INNER JOIN "friendly_id_slugs" ON "friendly_id_slugs"."sluggable_id" = "spree_products"."id"И" friendly_id_slugs "." dele_at" IS NULL И"friendly_id_slugs"."sluggable_type" =? WHERE ("spree_products"."Id" не равен NULL) и "spree_products". "Slug" = 'test' LIMIT 1 [["sluggable_type", "Spree::Product"]] Spree::Product Exists (0.2ms) ВЫБЕРИТЕ 1 КАК ИЗ "spree_products" ВНУТРЕННЕЕ СОЕДИНЕНИЕ "friendly_id_slugs" ON "friendly_id_slugs". "Sluggable_id" = "spree_products". "Id" И "friendly_id_slugs". "Удаленный_at" IS NULL AND "friendly_id_slugs"."Slugg". WHERE ("spree_products". "Id" не равен NULL) и "spree_products". "Slug" = 'test-123' LIMIT 1 [["sluggable_type", "Spree::Product"]] Spree::Product Exists (0.5ms) ВЫБЕРИТЕ 1 КАК один ИЗ "spree_products" ВНУТРЕННЕЕ СОЕДИНЕНИЕ "friendly_id_slugs" ON "friendly_id_slugs". "sluggable_id" = "spree_products". "id" И "friendly_id_slugs". "Удаленный_кат" IS NULL AND "friendly_id_slugsable" ".? WHERE ("spree_products". "Id" не равен NULL) И ("friendly_id_slugs"."Sluggable_type" = 'Spree::Product' AND "friendly_id_slugs"."Slug" = 'test-123') LIMIT 1 [["sluggable_type", "Spree::Product"]] Spree:: Вариант существует (0,5 мс) ВЫБЕРИТЕ 1 КАК ИЗ"spree_variants"ГДЕ"spree_variants"." Sku" = '123' И"spree_variants"." Удаленный_кат " IS NULL LIMIT 1 Spree::Product Exists (0,1ms) ВЫБЕРИТЕ 1 КАК ЕДИНИЦУ "spree_products" WHERE "spree_products"."Slug" = 'test-123' LIMIT 1 (0,1ms) транзакция отката
Gemfile
source 'https://rubygems.org'
ruby '2.2.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'spree_core', branch: '3-0-stable'
gem 'spree_api', branch: '3-0-stable'
gem 'spree_backend', branch: '3-0-stable'
gem 'spree_gateway', github: 'spree/spree_gateway', branch: '3-0-stable'
gem 'devise'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
# Access an IRB console on exception pages or by using <%= console %> in views
gem 'web-console', '~> 2.0'
end
group :production do
# Use PostgreSQL as the database for Active Record
gem 'pg', '0.18.2'
# Use rails_12 factor to enable serving assets in production and setting your logger to standard out.
gem 'rails_12factor', '0.0.3'
end
1 ответ
Я удалил
delegate_belongs_to :product, :delivery_on
из моего файла product_decorator.rb, и это решило проблему.
Честно говоря, я не совсем понял, что делает Delegate_belongs_to, но я добавил его, потому что официальный учебник по переопределению defree defreedes дает нам указание сделать это:
Нам также нужно делегировать sale_price в основной вариант, чтобы заставить работать обновленную форму редактирования продукта.
Мы можем сделать это, создав новый файл app / models / spree / product_decorator.rb и добавив в него следующее содержимое:
модуль Spree Product.class_eval do Delegate_belongs_to:master,:sale_price end end
Обратите внимание, я также пытался использовать делегат_белок_в: мастер,:delivery_on, но это тоже не сработало.