My Ticket对象引用Spree :: LineItem,它接受:ticket的嵌套属性。我已将@@ ticket_attributes添加到强参数和@@ line_item_attributes。我在模型中包含了has_one / belongs_to关系。为每个line_item创建一个功能齐全的嵌套表单以创建票证。
ticket.rb
class Ticket < ActiveRecord::Base
belongs_to :line_item
end
line_item_decorator.rb
Spree::LineItem.class_eval do
has_one :ticket
accepts_nested_attributes_for :ticket
end
permitted_attributes.rb
module Spree
module PermittedAttributes
ATTRIBUTES = [
...
:taxonomy_attributes,
:ticket_attributes,
:user_attributes,
:variant_attributes
]
mattr_reader *ATTRIBUTES
...
@@line_item_attributes = [:id, :variant_id, :quantity, :ticket_attributes]
...
@@ticket_attributes = [:id, :line_item_id, :first_name, :last_name, :start_date,
:end_date, :time]
...
end
end
当我点击'checkout'时,我可以看到params传递并正确嵌套,但是控制台给我一条消息'Unpermitted parameters:ticket'。
Started PATCH "/cart" for 127.0.0.1 at 2014-02-24 09:44:44 -0500
Processing by Spree::OrdersController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"YwCp2xUMd1Zc/v4eWfmMbFMiJdUQo+YYp/86nvSw5nc=", "order"=>{"line_items_attributes"=>{"0"=>{"quantity"=>"2", "ticket"=>{"first_name"=>"Nasty", "last_name"=>"Coffee", "start_date(1i)"=>"2014", "start_date(2i)"=>"2", "start_date(3i)"=>"24"}, "id"=>"23"}}, "coupon_code"=>""}, "checkout"=>""}
Spree::Preference Load (0.4ms) SELECT "spree_preferences".* FROM "spree_preferences" WHERE "spree_preferences"."key" = 'spree/frontend_configuration/locale' LIMIT 1
Spree::Order Load (0.4ms) SELECT "spree_orders".* FROM "spree_orders" WHERE "spree_orders"."number" IS NULL LIMIT 1
Spree::Order Load (0.3ms) SELECT "spree_orders".* FROM "spree_orders" WHERE "spree_orders"."id" = 6 AND "spree_orders"."currency" = 'USD' LIMIT 1
Spree::Adjustment Load (0.3ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."adjustable_type" = 'Spree::Order' AND "spree_adjustments"."adjustable_id" IN (6) ORDER BY spree_adjustments.created_at ASC
Spree::TokenizedPermission Load (0.3ms) SELECT "spree_tokenized_permissions".* FROM "spree_tokenized_permissions" WHERE "spree_tokenized_permissions"."permissable_id" = $1 AND "spree_tokenized_permissions"."permissable_type" = $2 ORDER BY "spree_tokenized_permissions"."id" ASC LIMIT 1 [["permissable_id", 6], ["permissable_type", "Spree::Order"]]
Unpermitted parameters: ticket
(0.1ms) BEGIN
Spree::LineItem Load (0.4ms) SELECT "spree_line_items".* FROM "spree_line_items" WHERE "spree_line_items"."order_id" = $1 AND "spree_line_items"."id" IN (23) ORDER BY created_at ASC [["order_id", 6]]
Spree::Payment Load (0.2ms) SELECT "spree_payments".* FROM "spree_payments" WHERE "spree_payments"."order_id" = $1 AND "spree_payments"."state" = 'completed' [["order_id", 6]]
Spree::LineItem Load (0.2ms) SELECT "spree_line_items".* FROM "spree_line_items" WHERE "spree_line_items"."order_id" = $1 ORDER BY created_at ASC [["order_id", 6]]
Spree::Adjustment Load (0.3ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."adjustable_id" = $1 AND "spree_adjustments"."adjustable_type" = $2 AND "spree_adjustments"."eligible" = 't' ORDER BY spree_adjustments.created_at ASC [["adjustable_id", 6], ["adjustable_type", "Spree::Order"]]
Spree::Adjustment Load (0.5ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."order_id" = $1 AND "spree_adjustments"."originator_type" = 'Spree::TaxRate' [["order_id", 6]]
Spree::Payment Load (0.4ms) SELECT "spree_payments".* FROM "spree_payments" WHERE "spree_payments"."order_id" = $1 AND ("spree_payments"."state" NOT IN ('failed', 'invalid')) [["order_id", 6]]
CACHE (0.0ms) SELECT "spree_payments".* FROM "spree_payments" WHERE "spree_payments"."order_id" = $1 AND "spree_payments"."state" = 'completed' [["order_id", 6]]
CACHE (0.0ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."adjustable_id" = $1 AND "spree_adjustments"."adjustable_type" = $2 AND "spree_adjustments"."eligible" = 't' ORDER BY spree_adjustments.created_at ASC [["adjustable_id", 6], ["adjustable_type", "Spree::Order"]]
CACHE (0.0ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."order_id" = $1 AND "spree_adjustments"."originator_type" = 'Spree::TaxRate' [["order_id", 6]]
CACHE (0.0ms) SELECT "spree_payments".* FROM "spree_payments" WHERE "spree_payments"."order_id" = $1 AND ("spree_payments"."state" NOT IN ('failed', 'invalid')) [["order_id", 6]]
(0.1ms) COMMIT
something
(0.1ms) BEGIN
(0.1ms) COMMIT
something 1
Spree::Shipment Exists (0.2ms) SELECT 1 AS one FROM "spree_shipments" WHERE "spree_shipments"."order_id" = $1 LIMIT 1 [["order_id", 6]]
Spree::Activator Load (0.3ms) SELECT "spree_activators".* FROM "spree_activators" WHERE (starts_at IS NULL OR starts_at < '2014-02-24 14:44:44.387522') AND (expires_at IS NULL OR expires_at > '2014-02-24 14:44:44.387735') AND (event_name LIKE 'spree.order.contents_changed%')
CACHE (0.0ms) SELECT "spree_payments".* FROM "spree_payments" WHERE "spree_payments"."order_id" = $1 AND "spree_payments"."state" = 'completed' [["order_id", 6]]
CACHE (0.0ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."adjustable_id" = $1 AND "spree_adjustments"."adjustable_type" = $2 AND "spree_adjustments"."eligible" = 't' ORDER BY spree_adjustments.created_at ASC [["adjustable_id", 6], ["adjustable_type", "Spree::Order"]]
CACHE (0.0ms) SELECT "spree_adjustments".* FROM "spree_adjustments" WHERE "spree_adjustments"."order_id" = $1 AND "spree_adjustments"."originator_type" = 'Spree::TaxRate' [["order_id", 6]]
CACHE (0.0ms) SELECT "spree_payments".* FROM "spree_payments" WHERE "spree_payments"."order_id" = $1 AND ("spree_payments"."state" NOT IN ('failed', 'invalid')) [["order_id", 6]]
Redirected to http://localhost:3000/checkout/address
Completed 302 Found in 31ms (ActiveRecord: 4.9ms)
_line_item.html.erb
<% variant = line_item.variant -%>
<%= order_form.fields_for :line_items, line_item do |item_form| -%>
<tr class="<%= cycle('', 'alt') %> line-item">
<td class="cart-item-image" data-hook="cart_item_image">
<% if variant.images.length == 0 %>
<%= link_to small_image(variant.product), variant.product %>
<% else %>
<%= link_to image_tag(variant.images.first.attachment.url(:small)), variant.product %>
<% end %>
</td>
<td class="cart-item-description" data-hook="cart_item_description">
<h4><%= link_to line_item.name, product_path(variant.product) %></h4>
<%= variant.options_text %>
<% if @order.insufficient_stock_lines.include? line_item %>
<span class="out-of-stock">
<%= Spree.t(:out_of_stock) %> <br />
</span>
<% end %>
<span class="line-item-description" data-hook="line_item_description">
<%= line_item_description_text(line_item.description) %>
</span>
</td>
<td class="cart-item-price" data-hook="cart_item_price">
<%= line_item.single_money.to_html %>
</td>
<td class="cart-item-quantity" data-hook="cart_item_quantity">
<%= item_form.number_field :quantity, :min => 0, :class => "line_item_quantity", :size => 5 %>
</td>
<td class="cart-item-total" data-hook="cart_item_total">
<%= line_item.display_amount.to_html unless line_item.quantity.nil? %>
</td>
<td class="cart-item-delete" data-hook="cart_item_delete">
<%= link_to image_tag('icons/delete.png'), '#', :class => 'delete', :id => "delete_#{dom_id(line_item)}" %>
</td>
<%= item_form.fields_for @ticket do |t| %>
<tr>
<td class="line_item_ticket">
<%= t.label :first_name %>
<%= t.text_field :first_name%>
</td>
<td class="line_item_ticket">
<%= t.label :last_name %>
<%= t.text_field :last_name%>
</td>
<td class="line_item_ticket">
<%= t.label :start_date %>
<%= t.date_select :start_date %>
</td>
</tr>
<% end -%>
</tr>
<% end -%><% variant = line_item.variant -%>
<%= order_form.fields_for :line_items, line_item do |item_form| -%>
<tr class="<%= cycle('', 'alt') %> line-item">
<td class="cart-item-image" data-hook="cart_item_image">
<% if variant.images.length == 0 %>
<%= link_to small_image(variant.product), variant.product %>
<% else %>
<%= link_to image_tag(variant.images.first.attachment.url(:small)), variant.product %>
<% end %>
</td>
<td class="cart-item-description" data-hook="cart_item_description">
<h4><%= link_to line_item.name, product_path(variant.product) %></h4>
<%= variant.options_text %>
<% if @order.insufficient_stock_lines.include? line_item %>
<span class="out-of-stock">
<%= Spree.t(:out_of_stock) %> <br />
</span>
<% end %>
<span class="line-item-description" data-hook="line_item_description">
<%= line_item_description_text(line_item.description) %>
</span>
</td>
<td class="cart-item-price" data-hook="cart_item_price">
<%= line_item.single_money.to_html %>
</td>
<td class="cart-item-quantity" data-hook="cart_item_quantity">
<%= item_form.number_field :quantity, :min => 0, :class => "line_item_quantity", :size => 5 %>
</td>
<td class="cart-item-total" data-hook="cart_item_total">
<%= line_item.display_amount.to_html unless line_item.quantity.nil? %>
</td>
<td class="cart-item-delete" data-hook="cart_item_delete">
<%= link_to image_tag('icons/delete.png'), '#', :class => 'delete', :id => "delete_#{dom_id(line_item)}" %>
</td>
<%= item_form.fields_for @ticket do |t| %>
<tr>
<td class="line_item_ticket">
<%= t.label :first_name %>
<%= t.text_field :first_name%>
</td>
<td class="line_item_ticket">
<%= t.label :last_name %>
<%= t.text_field :last_name%>
</td>
<td class="line_item_ticket">
<%= t.label :start_date %>
<%= t.date_select :start_date %>
</td>
</tr>
<% end -%>
</tr>
<% end -%>
orders_controller#修改
module Spree
class OrdersController < Spree::StoreController
ssl_required :show
before_filter :check_authorization
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
helper 'spree/products', 'spree/orders'
respond_to :html
def show
@order = Order.find_by_number!(params[:id])
end
def update
@order = current_order(lock: true)
unless @order
flash[:error] = Spree.t(:order_not_found)
redirect_to root_path and return
end
if @order.update_attributes(order_params)
puts "something"
@order.line_items = @order.line_items.select {|li| li.quantity > 0 }
puts "something 1"
@order.ensure_updated_shipments
return if after_update_attributes
fire_event('spree.order.contents_changed')
respond_with(@order) do |format|
format.html do
if params.has_key?(:checkout)
@order.next if @order.cart?
redirect_to checkout_state_path(@order.checkout_steps.first)
else
redirect_to cart_path
end
end
end
else
respond_with(@order)
end
end
# Shows the current incomplete order from the session
def edit
@ticket = Ticket.new
@order = current_order || Order.new
associate_user
end
# Adds a new item to the order (creating a new order if none already exists)
def populate
populator = Spree::OrderPopulator.new(current_order(create_order_if_necessary: true), current_currency)
if populator.populate(params.slice(:products, :variants, :quantity))
current_order.ensure_updated_shipments
fire_event('spree.cart.add')
fire_event('spree.order.contents_changed')
respond_with(@order) do |format|
format.html { redirect_to cart_path }
end
else
flash[:error] = populator.errors.full_messages.join(" ")
redirect_to :back
end
end
def empty
if @order = current_order
@order.empty!
end
redirect_to spree.cart_path
end
def accurate_title
if @order && @order.completed?
Spree.t(:order_number, :number => @order.number)
else
Spree.t(:shopping_cart)
end
end
def check_authorization
session[:access_token] ||= params[:token]
order = Spree::Order.find_by_number(params[:id]) || current_order
if order
authorize! :edit, order, session[:access_token]
else
authorize! :create, Spree::Order
end
end
private
def order_params
if params[:order]
params[:order].permit(*permitted_order_attributes)
else
{}
end
end
def after_update_attributes
coupon_result = Spree::Promo::CouponApplicator.new(@order).apply
if coupon_result[:coupon_applied?]
flash[:success] = coupon_result[:success] if coupon_result[:success].present?
return false
else
flash.now[:error] = coupon_result[:error]
respond_with(@order) { |format| format.html { render :edit } }
return true
end
end
end
end
为什么ticket
不被接受?
@Kirt Thorat非常感谢。我确实看过那个并且params正在core / lib / spree / core / controller_helpers / strong_parameters.rb中设置:
def permitted_order_attributes
permitted_checkout_attributes + [
:line_items_attributes => permitted_line_item_attributes
]
end
我如何包含ticket_attributes?
修改
我决定忘记这张票,只是扩展line_item。尽管如此,仍然有同样的问题。我尝试将{start_date属性添加到order_params
这样(b / c start_date是date_select
:
def order_params
if params[:order]
params[:order].permit(*permitted_order_attributes, :"start_date(1i)")
else
{}
end
end
和此:
def order_params
if params[:order]
params[:order].permit(*permitted_order_attributes, :start_date)
else
{}
end
end
答案 0 :(得分:1)
在Spree::OrdersController#update
中,您试图update
不允许的属性ticket
。
因此,允许ticket
作为Orders
模型的OrdersController(order_params方法)中的强参数。
答案 1 :(得分:1)
你可以直接将属性添加到强参数中,以便在core / lib / spree / core / controller_helpers / strong_parameters.rb permitted_*_attributes
中的顺序在api命名空间中设置,这种方式让我失望。当我在这里添加start_date时,我停止了Unpermitted parameters :your_attribute
。
@Kirti Thorat感谢您的回复。我之所以不接受你的答案,只是因为我已经将问题跟进了该方法并且改变了该方法并没有提供所需的结果。
这就是我必须做的事情。
def permitted_order_attributes
permitted_checkout_attributes + [
:line_items_attributes => permitted_line_item_attributes,
:start_date => :start_date
]
end