【问题标题】:Change price parameter based on form input根据表单输入更改价格参数
【发布时间】:2012-12-18 08:10:31
【问题描述】:

我有一个 Rails 表单,用户可以在其中选择每小时或每天购买产品。我正在使用购物车来跟踪购买的每件商品。提交表单时,购物车会传递行项目对象。我需要根据用户选择每小时还是每天购买来更改商品的价格并更改为成本计算。我不是我应该如何测试参数以及是否应该在项目的模型或控制器中执行此操作。

我的代码如下。感谢您的帮助!

填写的表格

<%= form_for LineItem.new do |f| %>
        <p><%= render :partial => "price" %> / 
            <%= f.select :day_or_hour, [['day', 'day'], ['hour', 'hour']], :id => 'day_or_hour' %>
    <div class="gearside_date_main">
        <h3 style="font-family: 'RockSaltRegular', 'JosefinSansStdLight', Helvetica, Arial, sans-serif;color: #71a41e; font-size: 16px; margin: 15px 0 5px 15px;">Rental Date</h3>      
            <%= f.text_field :rentstart, id: 'rentstart', :value => "Pickup"  %>
            <%= f.text_field :rentend, id: 'rentend', :value => "Drop Off"  %>
            <%= image_tag('calendar.png', :style => "float:left; padding-top: 8px") %>
            <%= f.hidden_field :gear_id, :value => @gear.id %>
            </br></br>
            <div class="gear_time_schedule hourlyshowhide">
            <span class="gear_time_schedule_container">
                <%= f.label :starthour, 'Pick Up Time', class: 'labeltext' %>
                <%= f.text_field :starthour, id: 'starthour',  :value => '' %>
            </span>
            <span class="gear_time_schedule_container">
                <%= f.label :endhour, 'Drop Off Time', class: 'labeltext' %>
                <%= f.text_field :endhour, id: 'endhour', :value => '' %>
            </span>
        </div>
            <%= f.submit "", id: 'rent_it' %>
        <% end %>

齿轮模型

class Gear < ActiveRecord::Base
  belongs_to :user
  has_many :line_items

  def hourly_price
    price/24
  end
end

订单项模型

class LineItem < ActiveRecord::Base
  belongs_to :cart
  belongs_to :gear

  def total_price
    gear.price * quantity
  end

  def set_rentprice price
   self.rentprice = price
  end

end

订单项数据库中的参数

  `id` int(11) NOT NULL AUTO_INCREMENT,
  `gear_id` int(11) DEFAULT NULL,
  `cart_id` int(11) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `quantity` int(11) DEFAULT '1',
  `rentstart` date DEFAULT NULL,
  `rentend` date DEFAULT NULL,
  `rentprice` decimal(10,0) DEFAULT NULL,
  `starthour` varchar(255) DEFAULT NULL,
  `endhour` varchar(255) DEFAULT NULL,
  `day_or_hour` varchar(255) DEFAULT NULL,
  `order_id` int(11) DEFAULT NULL,

在 LineItem 控制器中创建操作

 def create
    @cart = current_cart
    case params[:day_or_hour]
     when 'day'
      price = Gear.weekly_price
     when 'hour'
      price = Gear.hourly_price # these methods have to be converted to class methods
    end
    gear = Gear.find(params[:line_item][:gear_id])
lineitem = LineItem.new(params[:line_item])
lineitem.set_rentprice price
@line_item = @cart.add_gear(lineitem, gear.id)

        respond_to do |format|
          if @line_item.save
            format.html { redirect_to @line_item.cart }
            format.json { render json: @line_item, status: :created, location: @line_item }
          else
            format.html { render action: "new" }
            format.json { render json: @line_item.errors, status: :unprocessable_entity }
          end
        end
      end

购物车模型

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy

  def add_gear(lineitem, gear_id)
    current_item = line_items.find_by_gear_id(gear_id)
    if current_item
      current_item.quantity += 1
    else
      current_item = line_items.build(lineitem)
    end
    current_item
  end

  def total_price
    line_items.to_a.sum { |item| item.total_price }
  end

结束

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    请允许我提出一个重构的建议。

    这看起来很适合多对多关联。 安装nested_form gem。有关嵌套表单的更多信息,请查看railscasts

    class Cart < ActiveRecord::Base
     has_many :line_items
     has_many :gears, through: line_items
    
     attr_accessible :line_items_attributes
    
     accepts_nested_attributes_for :line_items
    
     def total_price
      gears.sum(:price)
     end
    end
    
    class Gear < ActiveRecord::Base
     has_many :line_items
     has_many :carts, through: line_items
    end
    
    class LineItem < ActiveRecord::Base
     belongs_to :cart
     belongs_to :gear
    
     attr_accessible :cart_id, :gear_id
    end
    

    现在,在您的购物车控制器中

    def new
     @cart = Cart.new
    end
    

    我使用simple_form 以获得更清晰的视图。你应该考虑使用它。

    Nested_form 将负责通过 jquery 添加和删除项目 :)

    <%= simple_nested_form_for @cart do |f| %>
      <%= f.simple_fields_for :line_items do |item| %>
       <%= item.input :rentstart %>
       <%= item.input :rentend %>
    
       #Select your gear like this
       <%= item.association :gear, as: :collection, label_method: :gear.nameorwhatever, value_method: :gear.id %>
    
       #Remove items using this link
       <%= item.link_to_remove "Remove this task" %>
      <% end %>
    
      #Add new item
      <p><%= f.link_to_add "Add an item", :tasks %></p>
    <% end %>
    

    您的购物车控制器的创建操作将是标准的。 Accepts_nested_attributes for 会神奇地更新你的 lineItems。

    【讨论】:

    • Rahul,我不确定我是否完全理解你建议的这些内容,所以我更新了我的最佳猜测。我进行了一些修改,因为我已经在名为“rentprice”的行项目中有一个字段,我在其中传递了价格参数。现在我得到一个错误未定义的方法`set_rentprice'
    • lineitem 需要是 LineItem 模型的一个实例。如果您使用 params[:line_item] 创建实例,那么也许可以尝试这样的事情。 lineitem = LineItem.new(params[:line_item])。其次是 lineitem.set_rentprice 价格
    • 顺便说一句,由于您将 lineItem 保存在购物车中,请也向我展示该模型。此外,由于您似乎没有在 Lineitem 中保留任何内容,我认为它不需要从 ActiveRecord 继承。也许一旦你粘贴你的购物车模型,我会改变我的答案。请原谅我的第一次尝试。没有耐心看完你所有的代码。
    • 我更新了我的代码。我得到了#<0x007ff9cbb6b7b0>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多