Los usuarios "administradores" crean eventos. Entonces, cada evento tiene su propia URL como "eventos / 1". En el sitio público (es decir, no se requiere autenticación). Un miembro del público puede comprar entradas para el evento. Todo lo que el administrador tiene que hacer es publicar la URL pública, es decir, "evento / 1" y genera un formulario para que el comprador de entradas lo complete.

No puedo hacer que los compradores de entradas se asocien con su evento respectivo (es decir, evento / 1). Aquí está el resultado de ejecutar Event.first.ticket_buyers en el símbolo del sistema que no muestra nada en la matriz, aunque he llenado el primer evento con datos de ticket_buyer usando el formulario de la aplicación (no el comando api):

irb(main):001:0> Event.first.ticket_buyers
  Event Load (0.0ms)  SELECT  "events".* FROM "events"  ORDER BY "events"."id" ASC LIMIT 1
  TicketBuyer Load (1.0ms)  SELECT "ticket_buyers".* FROM "ticket_buyers" WHERE "ticket_buyers"."event_id" = ?  [["event_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy []>

Modelo de evento

class Event < ActiveRecord::Base
  belongs_to :admin
  has_many :ticket_buyers, dependent: :destroy
end

Modelo TicketBuyer

class TicketBuyer < ActiveRecord::Base
  belongs_to :event
end

Controlador de eventos

class EventsController < ApplicationController
  before_filter :authenticate_admin!, :except => :show

  def index 
    @events = current_admin.events
  end

  def show     
    @event = Event.find(params[:id])
    @ticket_buyers = TicketBuyer.new
  end

  def new 
    @event = current_admin.events.build
    @event.admin = current_admin
  end

  def create
    @event = current_admin.events.build(event_params)

    if @event.save
      redirect_to @event
    else
      render 'new'
    end
  end

  private

  def event_params
      params.require(:event).permit(:name_of_event, ticket_buyer_attributes:  [:full_name,  :number_of_tickets])
  end
end

Controlador de compradores de entradas

class TicketBuyersController < ApplicationController
  before_action :authenticate_admin!, :except => [:new, :create]

  def index
    @ticket_buyer = TicketBuyer.all
  end

  def show    
    @ticket_buyer = TicketBuyer.find(params[:id])
    @event = Event.find(params[:event_id])
  end

  def new
    @ticket_buyer = TicketBuyer.new
  end

  def create  
    @ticket_buyer = TicketBuyer.new(ticket_buyer_params)
    if @ticket_buyer.save
      redirect_to localhost:3000
    else
      render('new')
    end
  end

  private

  def set_ticket_buyer
    @ticket_buyer = Ticket_buyer.find(params[:id])
  end

  def ticket_buyer_params
    params.require(:ticket_buyer).permit(:full_name,  :number_of_tickets)
  end
end

Esquema de base de datos

ActiveRecord::Schema.define(version: 20160705212350) do

  create_table "admins", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "full_name"
   end

  add_index "admins", ["email"], name: "index_admins_on_email", unique: true
  add_index "admins", ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true

  create_table "events", force: :cascade do |t|
    t.text     "name_of_event"
    t.integer  "admin_id"
    t.datetime "created_at",           null: false
    t.datetime "updated_at",           null: false
  end

  add_index "events", ["admin_id"], name: "index_events_on_admin_id"

  create_table "ticket_buyers", force: :cascade do |t|
    t.text     "full_name"
    t.integer  "event_id"
    t.datetime "created_at",          null: false
    t.datetime "updated_at",          null: false
  end

  add_index "ticket_buyers", ["event_id"], name: "index_ticket_buyers_on_event_id"
end

routes.rb

Rails.application.routes.draw do
  devise_for :admins
    resources :events do
      resources :ticket_buyers do
  end
end

ticket_buyers / index.html.erb

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

  <table class='table table-striped table-hover'>
    <thead>
      <tr>
        <th>Name</th>
        <th>Number of tickets</th>
        <th colspan="4"></th>
      </tr>
    </thead>

    <tbody>
      <% @ticket_buyer.each do |ticket_buyer| %>
      <tr class="<%= cycle('list_line_odd', 'list_line_even') %>">
        <tr>
          <td><%= link_to ticket_buyer.full_name %></td>
          <td><%= link_to ticket_buyer.number_of_tickets %></td>        
        </tr>
     <% end %>
  </tbody>
  </table>
<%= link_to 'Back', events_path %>
0
Tkendall 28 jul. 2016 a las 18:12

2 respuestas

La mejor respuesta

En su acción de creación de TicketBuyer, debe asociar el registro con el evento después de crearlo:

class TicketBuyersController < ApplicationController
  before_action :authenticate_admin!, :except => [:new, :create]

  def create  
    @ticket_buyer = TicketBuyer.new(ticket_buyer_params)

    if @ticket_buyer.save
      # This line below links it to your event
      Event.find(params[:event_id]).ticket_buyers << @ticket_buyer
      redirect_to localhost:3000
    else
      render('new')
    end  
  end

También puede crear ticket_buyer utilizando el evento en sí como se muestra a continuación:

def create  
  @ticket_buyer = Event.find(params[:event_id]).ticket_buyers.new(ticket_buyer_params)

  if @ticket_buyer.save
    redirect_to localhost:3000
  else
    render('new')
  end  

Esto agregará automáticamente el event_id correcto al modelo al construirlo. Además, asegúrese de haber realizado una migración agregando la columna event_id a la tabla ticket_buyers.

Actualizar:

Para mostrar los ticket_buyers correctos en la acción de índice, debe cargar el evento en su lugar, luego usar puede recorrer los ticket_buyers asociados para ese evento:

TicketBuyersController:

def index
  @event = Event.find(params[:event_id])
end

Vista de índice:

<tbody>
  <% @event.ticket_buyers.each do |ticket_buyer| %>
  <tr class="<%= cycle('list_line_odd', 'list_line_even') %>">
    <tr>
      <td><%= link_to ticket_buyer.full_name %></td>
      <td><%= link_to ticket_buyer.number_of_tickets %></td>        
    </tr>
 <% end %> 
0
RichardAE 31 jul. 2016 a las 18:22

Eso se debe a que no está guardando la identificación del evento en el registro ticket_buyer. Me pregunto por qué tampoco está validando la presencia de ticket_buyers. Una solución rápida inmediata es agregar su event_id a su ticket_buyer_params así:

def ticket_buyer_params  
  params.require(:ticket_buyer).permit(:full_name, :number_of_tickets, :event_id)
end
0
oreoluwa 28 jul. 2016 a las 15:47