【问题标题】:Can't add custom product attribute via admin无法通过管理员添加自定义产品属性
【发布时间】:2015-12-10 23:16:36
【问题描述】:

我是 Spreecommerce 的新手,无法通过管理界面创建具有自定义属性“delivery_on”的产品。简而言之,我创建了 migrate,product_decorator.rb,将新属性添加到允许的属性,为管理页面创建一个 deface 文件。但是,当我尝试通过管理界面创建新产品时,我收到一条错误消息,指出“Delivery on can't be blank”。

非常感谢您的帮助!

我正在使用 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 中,插入对“更改”方法的更改:

    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 并更新了架构。但它首先清除了数据库。不确定这是不是理想的方法(遵循stackoverflow thread 上的指导)

  • 在 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 中,创建 deface 文件 '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 并尝试创建新产品,但我收到一条错误消息,指出“Delivery on can't be blank。”

  • 这是日志中的输出

    于 2015 年 9 月 14 日 22:24:20 +0200 开始为 ::1 发布“/admin/products” Spree::Admin::ProductsController#create as HTML 处理 参数:{"utf8"=>"✓", "authenticity_token"=>"O6BkeJEhquvCnu5nrIHwYYUZqkif8C9MqKRf4+qvjxH5UqkM9m+QDwvxcfBFqE4QcwPnDU/wrwAKGyk+wzVz8Q==", "product"=>{"name"=>"test", "sku"= >"123", "prototype_id"=>"", "price"=>"99", "available_on"=>"2015/09/12", "delivery_on"=>"2015/09/30", "shipping_category_id "=>"1"}, "按钮"=>""} Spree::Preference Load (0.1ms) SELECT "spree_preferences".* FROM "spree_preferences" WHERE "spree_preferences"."key" = ?限制 1 [["key", "spree/backend_configuration/locale"]] 用户负载 (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]] (0.1ms)从“spree_roles”内部加入“spree_roles_users”中选择计数(*)在“spree_roles”。“id”=“spree_roles_users”。“role_id”在哪里“spree_roles_users”。“user_id”=? AND "spree_roles"."name" = ? [["user_id", 1], ["name", "admin"]] (0.2ms) 开始交易 Spree::Product Exists (1.1ms) SELECT 1 AS one FROM "spree_products" INNER JOIN "friendly_id_slugs" ON "friendly_id_slugs"."sluggable_id" = "spree_products"."id" AND "friendly_id_slugs"."deleted_at" IS NULL AND " friendly_id_slugs"."sluggable_type" = ? WHERE ("spree_products"."id" IS NOT NULL) AND "spree_products"."slug" = 'test' LIMIT 1 [["sluggable_type", "Spree::Product"]] Spree::Product Exists (0.2ms) SELECT 1 AS one FROM "spree_products" INNER JOIN "friendly_id_slugs" ON "friendly_id_slugs"."sluggable_id" = "spree_products"."id" AND "friendly_id_slugs"."deleted_at" IS NULL AND " friendly_id_slugs"."sluggable_type" = ? WHERE ("spree_products"."id" IS NOT NULL) AND "spree_products"."slug" = 'test-123' LIMIT 1 [["sluggable_type", "Spree::Product"]] Spree::Product Exists (0.5ms) SELECT 1 AS one FROM "spree_products" INNER JOIN "friendly_id_slugs" ON "friendly_id_slugs"."sluggable_id" = "spree_products"."id" AND "friendly_id_slugs"."deleted_at" IS NULL AND " friendly_id_slugs"."sluggable_type" = ? WHERE ("spree_products"."id" IS NOT NULL) AND ("friendly_id_slugs"."sluggable_type" = 'Spree::Product' AND "friendly_id_slugs"."slug" = 'test-123') 限制 1 [["sluggable_type ", "狂欢::产品"]] Spree::Variant Exists (0.5ms) SELECT 1 AS one FROM "spree_variants" WHERE "spree_variants"."sku" = '123' AND "spree_variants"."deleted_at" IS NULL LIMIT 1 Spree::Product Exists (0.1ms) SELECT 1 AS one FROM "spree_products" WHERE "spree_products"."slug" = 'test-123' LIMIT 1 (0.1ms) 回滚事务

宝石文件

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

【问题讨论】:

  • 您的迁移正在添加 active 列,而不是 delivery_on 列 - 您粘贴了正确的迁移吗?
  • 好收获。我最初复制了错误的迁移。使用正确的迁移更新了帖子。谢谢@MikeManfrin
  • 我相信您需要将 delivery_on 添加到控制器的强参数中;可能不允许通过,因此该应用正在尝试制造没有按时交货的产品(这会导致您的验证失败)。
  • @MikeManfrin 我认为强参数也存在问题。我在 github 上从 spree 贡献者那里找到了这个 thread,并遵循了他们的解决方案。在我的帖子中,请参阅 app/controllers/application_controllers.rb 中关于将 delivery_on 添加到 PermittedAttributes 的部分。当我启动控制台并运行 Spree::PermittedAttributes.product_attributes 时,delivery_on 在允许的属性列表中返回,所以我相信它已被添加。还有其他想法吗?感谢您的帮助。

标签: ruby-on-rails spree


【解决方案1】:

我删除了

delegate_belongs_to :product, :delivery_on

来自我的 product_decorator.rb 文件,这解决了问题。

说实话,我并没有真正理解 delegate_belongs_to 是做什么的,但我添加了它,因为官方 Spree deface overrides tutorial 指示我们这样做:

我们还需要将 sale_price 委托给主变体,以便 让更新后的产品编辑表单生效。

我们可以通过创建一个新文件来做到这一点 app/models/spree/product_decorator.rb 并添加以下内容 给它:

module Spree Product.class_eval 做 delegate_belongs_to :master, :sale_price end end

注意,我也尝试过使用 delegate_belongs_to :master, :delivery_on ,但也没有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多