Кнопка, которая увеличивает значение в БД, аналогичное кнопке "Like it" на YouTube - rails

Это мой первый вопрос по stackru, и я ожидаю, что в этом нет ничего плохого. Итак, поехали...
Я разрабатываю программу, которая очень проста для практики, она будет хранить название, цену, штрих-код и количество продуктов. Я мог бы добавить больше продуктов или увеличить количество продуктов.

Я не знаю, как создать кнопки "+" и "-", которые увеличивают и уменьшают количественное значение моего объекта продукта. И я бы предпочел использовать метод post, потому что он не позволяет браузеру создавать историю при каждом нажатии кнопки "плюс". Здесь есть похожие вопросы о stackru, но их ответы мне не помогли, и версии rails не были 4.

РЕДАКТИРОВАТЬ: вид

<p id="notice"><%= notice %></p>    

<h1>Listing Produtos</h1>    

<table>
  <thead>
    <tr>
      <th>Qntd</th>
      <th>Type</th>
      <th>Features</th>
      <th>Barcode</th>
      <th>Img</th>
      <th>Price</th>
      <th colspan="3"></th>
    </tr>
  </thead>    

  <tbody>
    <% @produtos.each do |produto| %>
      <tr>
        <td style="vertical-align:middle"><%= produto.quantidade %></td>
        <td style="vertical-align:middle"><%= produto.tipo %></td>
        <td style="vertical-align:middle"><%= produto.features %></td>
        <td style="vertical-align:middle"><%= produto.barcode %></td>
        <td style="vertical-align:middle"><%= link_to image_tag(produto.img, :border=>0, :width=>240, :height=>160), edit_produto_path(produto)%></td>
        <td style="vertical-align:middle"><%= number_to_currency(produto.price) %></td>
        <td style="vertical-align:middle"><%= button_to '+', produto,  action: :menosum, data: { confirm: 'Are you sure?' } %></td>
        <td style="vertical-align:middle"><%= button_to '-', produto, action: :menosum, data: { confirm: 'Are you sure?' } %></td> # these are the buttons i need help to fix
      </tr>
    <% end %>
  </tbody>
</table>    

<br>    

<%= link_to 'New Produto', new_produto_path %>

контроллер по умолчанию генерируется рельсами

class ProdutosController < ApplicationController
  before_action :set_produto, only: [:show, :edit, :update, :destroy]    

  # GET /produtos
  # GET /produtos.json
  def index
    @produtos = Produto.all
  end
  def maisum
    @produto.quantidade += 1
    @produto.save
  end
  def menosum
    @produto.quantidade -= 1
    @produto.save
  end    

  # GET /produtos/1
  # GET /produtos/1.json
  def show
  end    

  # GET /produtos/new
  def new
    @produto = Produto.new
  end    

  # GET /produtos/1/edit
  def edit
  end    

  # POST /produtos
  # POST /produtos.json
  def create
    @produto = Produto.new(produto_params)    

    respond_to do |format|
      if @produto.save
        format.html { redirect_to @produto, notice: 'Produto was successfully created.' }
        format.json { render :show, status: :created, location: @produto }
      else
        format.html { render :new }
        format.json { render json: @produto.errors, status: :unprocessable_entity }
      end
    end
  end    

  # PATCH/PUT /produtos/1
  # PATCH/PUT /produtos/1.json
  def update
    respond_to do |format|
      if @produto.update(produto_params)
        format.html { redirect_to @produto, notice: 'Produto was successfully updated.' }
        format.json { render :show, status: :ok, location: @produto }
      else
        format.html { render :edit }
        format.json { render json: @produto.errors, status: :unprocessable_entity }
      end
    end
  end    

  # DELETE /produtos/1
  # DELETE /produtos/1.json
  def destroy
    @produto.destroy
    respond_to do |format|
      format.html { redirect_to produtos_url, notice: 'Produto was successfully destroyed.' }
      format.json { head :no_content }
    end
  end    

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_produto
      @produto = Produto.find(params[:id])
    end    

    # Never trust parameters from the scary internet, only allow the white list through.
    def produto_params
      params.require(:produto).permit(:tipo, :features, :barcode, :img, :price, :quantidade)
    end
end

модель

class Produto < ActiveRecord::Base
    validates :quantidade, :tipo, :features, :barcode, :price, presence: true
    validates :price, numericality: {greater_than_or_equal_to: 0.01}
    validates :quantidade, numericality: {greater_than_or_equal_to: 0}
end

EDIT²: я не мог заставить link_to работать, он продолжает говорить No route matches {:action=>"menosum", :controller=>"produtos", :method=>:post} и я уже создал маршрут:

Rails.application.routes.draw do

  resources :produtos do

    member do

      post 'maisum', 'menosum'

    end

  end

  # The priority is based upon order of creation: first created -> highest priority.

  # See how all your routes lay out with "rake routes".    

  # You can have the root of your site routed with "root"

   root 'welcome#index'

Поэтому я решил попробовать button_to, и это сработало! Но не так, как я ожидал...:(Это мое мнение:

<p id="notice"><%= notice %></p>    

<h1>Listing Produtos</h1>    

<table>

  <thead>

    <tr>

      <th style="text-align: center">Qntd</th>

      <th style="text-align: center">Tipo <input type="text" name="produto[tipo]" id="produto_tipo" /></th>

      <th style="text-align: center">Features</th>

      <th style="text-align: center">Barcode</th>

      <th style="text-align: center">Img</th>

      <th style="text-align: center">Price</th>

      <th colspan="3"></th>

    </tr>

  </thead>    

  <tbody>

    <% @produtos.each do |produto| %>

      <tr>

        <td style="vertical-align:middle"><%= produto.quantidade %></td>

        <td style="vertical-align:middle"><%= produto.tipo %></td>

        <td style="vertical-align:middle"><%= produto.features %></td>

        <td style="vertical-align:middle"><%= produto.barcode %></td>

        <td style="vertical-align:middle"><%= link_to image_tag(produto.img, border: 0, width: 240, height: 160), edit_produto_path(produto)%></td>

        <td style="vertical-align:middle"><%= number_to_currency(produto.price) %></td>

        <td style="vertical-align:middle"><%= button_to '+', action: :maisum, id: produto, remote: true%></td>

        <td style="vertical-align:middle"><%= button_to '-', action: :menosum, id: produto, remote: true %></td>

      </tr>

    <% end %>

  </tbody>

</table>    

<br>    

<%= link_to 'New Produto', new_produto_path %>

Я ожидал включить функцию AJAX с опцией "remote: true", но он вернул ошибку, сообщающую MissingTemplate, наконец, я попытался добавить redirect_to action: "index" в конце моего действия контроллера. Но это заставляет страницу обновляться.

контроллер:

.
.
.
  def index

    @produtos = Produto.all

  end

  def maisum

    @produto = Produto.find(params[:id])

    @produto.quantidade += 1

    @produto.save

  end

  def menosum

    @produto = Produto.find(params[:id])

    @produto.quantidade -= 1

    @produto.save

    redirect_to action: "index"

  end
.
.
.

1 ответ

Итак, вам нужно сделать следующее:

  1. Создайте действие для лайка и действие для непохожего в вашем контроллере
  2. Определите основные компоненты маршрутов, используя ключевое слово member смотрите здесь для деталей
  3. Затем создайте кнопки в представлении с link_to указывая на ваши действия
  4. Также укажите, куда вы хотите перенаправиться (какой вид вы хотите видеть с render метод в контроллере)
Другие вопросы по тегам