I am practicing rails by developing a band application where Venues have many events and bands and those events and bands belong to the Venues.
I have foreign keys set up, I am just a little confused on how to display attributes of the venues controller within the Events index.html.erb
I want to show which specific Venue my event belongs to and vice versa.
This is my events controller
class EventsController < ApplicationController
def index
#events = Event.all
#should I store my venues in the index to show its values?
#venues = Venue.where(params[:id])
end
def edit
#events = Event.find(params[:id])
puts #events.inspect
end
def update
#events = Event.find(params[:id])
#events.update_attributes(name: params[:event][:name], date: params[:event][:date], alcohol_served: params[:event][:alcohol_served], venue_id: params[:event][:venue_id], band_id: params[:event][:band_id])
redirect_to action: 'index'
end
def destroy
#events=Event.find(params[:id])
#events.destroy
redirect_to action: 'index'
end
def new
#Events = Event.new
end
def create
#Events = Event.create(name: params[:event][:name], date: params[:event][:date], alcohol_served: params[:event][:alcohol_served], venue_id: params[:event][:venue_id], band_id: params[:event][:band_id])
#Events.save
redirect_to action: 'index'
end
end
Disregard some of my redirects they are only for test purposes
Here are my models
class Venue < ApplicationRecord
has_many :events
has_many :bands, through: :events
end
class Event < ApplicationRecord
belongs_to :venue
belongs_to :band
end
class Band < ApplicationRecord
has_many :events
end
If you have a Venue and want to know all the events taking place at this Venue: #events = Event.find_by(:venue_id venue.id)
If you have an event and want to find the venue
venue_id = Event.select(:venue_id).find(params[:id])
#venue = Venue.find(venue_id)
You can replace in params[:id] by event.id depending on the use case.
Related
I have the following code letting a user to create a new album through a join table with an extra params (creator).
In order to do it, my controller does 2 requests (one for creating the album object and the collaboration object / the other to update the collaboration object with the extra params).
I would like to know if there is a way to do this call with only one request. (add the extra "creator" params in the same time than the album creation)
Thank you.
albums_controller.rb
class AlbumsController < ApplicationController
def new
#album = current_user.albums.build
end
def create
#album = current_user.albums.build(album_params)
if current_user.save
#album.collaborations.first.update_attribute :creator, true
redirect_to user_albums_path(current_user), notice: "Saved."
else
render :new
end
end
private
def album_params
params.require(:album).permit(:name)
end
end
Album.rb
class Album < ApplicationRecord
# Relations
has_many :collaborations
has_many :users, through: :collaborations
end
Collaboration.rb
class Collaboration < ApplicationRecord
belongs_to :album
belongs_to :user
end
User.rb
class User < ApplicationRecord
has_many :collaborations
has_many :albums, through: :collaborations
end
views/albums/new
= simple_form_for [:user, #album] do |f|
= f.input :name
= f.button :submit
You can just add associated objects on the new album instance:
#album = current_user.albums.new(album_params)
#album.collaborations.new(user: current_user, creator: true)
When you call #album.save ActiveRecord will automatically save the associated records in the same transaction.
class AlbumsController < ApplicationController
def new
#album = current_user.albums.new
end
def create
#album = current_user.albums.new(album_params)
#album.collaborations.new(user: current_user, creator: true)
if #album.save
redirect_to user_albums_path(current_user), notice: "Saved."
else
render :new
end
end
private
def album_params
params.require(:album).permit(:name)
end
end
You are also calling current_user.save and not #album.save. The former does work due to fact that it causes AR to save the associations but is not optimal since it triggers an unessicary update of the user model.
I have a question for rails.
I have a User controller,
I have a Product controller.
I have a user id references in product:db.
How to puts User.product number in Html?
Firstly you need configure devise gem for authentication to your user model to add user_id column to your products table.
rails g migartion add_user_id_to_products user_id:integer:index
In your users model
class User < ApplicationRecord
has_many :products
end
In your products model
class Products < ApplicationRecord
belongs_to :user
end
As your user and products are associated through has_many and belongs_to.
you can as below in the products controller
class ProductsController < ApplicationController
def index
#products = Product.all
end
def new
#product = Product.new
end
def create
#product = current_user.products.build(product_params)
if #product.save
redirect_to edit_product_path(#product), notice: "Saved..."
else
render :new
end
end
private
def product_params
params.require(:product).permit( :title, :description, :category)
end
end
If the data is successfully saved into the database, you will find the user_id column of the products table filled with the id of the current_user.
To get all the products of a particular user
In your users controller show action
def show
#user_products = #user.products
end
The #user_products will have all the products belonging to the corresponding user.
So I've built a system of products and a shopping cart in my rails app. The goal I have is to add ids of the saved products from a cart to the user model. So in my cart view page there is a list of all added products in a cart and I want to add a save button which will save those products by their ids to the columns in users table. As an example, if current_user ads three products in the cart with ids 1,2,3 and clicks on "Save" button in a cart, I want to be able to save those three ids by integers to the three columns: product_one, product_two, product_three of the current_user.
So far these are my models:
class Item < ActiveRecord::Base
has_one :cart
end
class User < ActiveRecord::Base
has_one :cart
has_many :items, through: :cart
end
class Cart < ActiveRecord::Base
belongs_to :user
belongs_to :item
validates_uniqueness_of :user, scope: :item
end
My controllers:
class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]
respond_to :html, :json, :js
def index
#items = Item.where(availability: true)
end
def show
end
def new
#item = Item.new
end
def edit
end
def create
#item = Item.new(item_params)
#item.save
respond_with(#item)
end
def update
#item.update(item_params)
flash[:notice] = 'Item was successfully updated.'
respond_with(#item)
end
def destroy
#item.destroy
redirect_to items_url, notice: 'Item was successfully destroyed.'
end
private
def set_item
#item = Item.find(params[:id])
end
def item_params
params.require(:item).permit(:name, :description, :availability)
end
end
my cart controller:
class CartController < ApplicationController
before_action :authenticate_user!, except: [:index]
def add
id = params[:id]
if session[:cart] then
cart = session[:cart]
else
session[:cart] = {}
cart = session[:cart]
end
if cart[id] then
cart[id] = cart[id] + 1
else
cart[id] = 1
end
redirect_to :action => :index
end
def clearCart
session[:cart] = nil
redirect_to :action => :index
end
def index
if session[:cart] then
#cart = session[:cart]
else
#cart = {}
end
end
end
And I'm using Devise for authentication..
I think you may have misunderstood the Rails relations and how to use them. As the methods to define relation are pretty much literal, take a good look at your models and 'read' them.
An item has one cart
A cart belongs to a item
Does it make sense that an item has one cart? Wouldn't make more sense to a cart to have an item, or several?
A cart has one or more items
One item belongs to a cart
And then, you just translate that into rails methods:
class User < ActiveRecord::Base
has_one :cart
end
class Cart < ActiveRecord::Base
belongs_to :user #carts table must have a user_id field
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :cart #items table must have a cart_id field
end
Now, let's return to the literals. So, if I have a user and want to know what items he has in a cart, what do I do?
I know a user has one cart
I know that a cart has one or more items
So, to recover the items that a user has in a cart:
user.cart.items
And answering your original question, how to save the items to a user? You don't need to. If the user has a cart and this cart has items then, automatically, user has items (accessing them through the cart, as stated above).
New to stack! so Hello there ! I'm making a sample event booking app, that has event check out using stripe.
My set up is below
class Event < ActiveRecord::Base
belongs_to :user
has_many :tickets, :inverse_of => :event, dependent: :destroy
end
class Ticket < ActiveRecord::Base
belongs_to :event, :inverse_of => :tickets
end
class Booking < ActiveRecord::Base
belongs_to :event
belongs_to :ticket, :inverse_of => :bookings
has_one :sale, :inverse_of => :booking
end
class Sale < ActiveRecord::Base
belongs_to :booking, :inverse_of => :sale
belongs_to :ticket
end
class BookingsController < ApplicationController
before_filter :load_event
before_filter :load_ticket
def index
#bookings = #event.bookings
end
def new
#booking = Booking.new
end
private
def load_event
#event = Event.find(params[:event_id])
end
def load_ticket
#ticket = #event.tickets.find(params[:ticket_id])
end
def booking_params
params.require(:booking).permit(:buyer_name, :phone, :address, :order_quantity,:total_amount)
end
end
class TransactionsController < ApplicationController
before_filter :load_event
before_filter :load_booking
before_filter :load_ticket
def new
end
def pickup
#sale = Sale.find_by!(guid: params[:guid])
#booking = #sale.booking
end
def complete
#sale = Sale.find_by!(guid: params[:guid])
#booking = #sale.booking
end
if sale.save
StripeCharger.perform_async(sale.guid)
render json: { guid: sale.guid }
else
errors = sale.errors.full_messages
render json: {
error: errors.join(" ")
}, status: 400
end
end
def status
sale = Sale.find_by!(guid: params[:guid])
render json: { status: sale.state }
end
private
def load_event
#event = Event.find(params[:event_id])
end
def load_booking
#booking = #event.bookings.find(params[:booking_id])
end
def load_ticket
#ticket = #booking.ticket.find(params[:ticket_id])
end
end
#Stripe Checkout Routes
I left out a view minimal details within the models . But basically What I am trying to do is have a user enter Name, and quantity of the ticket and from submitin the booking redirect to the transaction new, in which I can carry out the sale model with Stripe Check out.
My ultimate goal of everything is to get the bookings quantity input multiplied with the ticket price to get a total amount to carry through Stripe. Do anyone have any suggestions on how to improve this break down. Of modeling a events, tickets, bookings to check out type of example. Sorry if how I'm breaking it down is noobish, I'm attempting to wrap my head around accomplishing this.
In transaction controller you don't need find on #booking.ticket
def load_ticket
#ticket = #booking.ticket.find(params[:ticket_id])
end
Since #booking has only one ticket, you just need #booking.ticket
I have set up an event booking application with ruby on rails where I have users who can create events and the general public can book events. I am having problems implementing the booking feature. This is what I have done so far.
Created a Booking resource and associated it with the event model. The booking model contains the following attributes
Booker name
Booker Email
event_id
The goal is to "create a booking" for a current event. However I do not know how to pass the "current_event" parameter to the booking controller and I am also not sure how to define a "current_event".
Update your routes file like this (rails 4):
EventManagement::Application.routes.draw do
resources :events do
resources :bookings
end
end
This will give you a "nested route" -- the route to bookings is always "nested" under events. To create a new booking for an event, you'll use the new_event_booking_path(#event) route and to view a list of all the bookings for the event it's just event_bookings_path(#event). Each of these routes will put the event_id into the params hash.
class BookingsController < ApplicationController
before_filter :load_event
def index
#bookings = #event.bookings
end
def new
#booking = #event.bookings.build
end
def create
#booking = #event.bookings.build booking_params
if #booking.save
..
else
...
end
end
private
def load_event
#event = Event.find params[:event_id]
end
def bookings_params
params.require(:bookings).permit(:booker_name, :booker_email)
end
end
Actually I don't think you should have a Booking resource, but rather an Event resource and only a Booking model. The booking should happen in the events_controller, where you can easily specify the current #event.
Were I you, I would do the following.
# app/models/event.rb
class Event < ActiveRecord::Base
has_many :bookings
end
# /models/booking.rb
class Booking < ActiveRecord::Base
belongs_to :event
end
# app/controllers/events_controller.rb
class EventsController < ApplicationController
# POST /events/{:id}/book
def book_new_ticket
#event = Event.find(params[:id])
if #event.bookings.where(email: params[:email]).count > 0
redirect_to '/somewhere', alert: "THIS EMAIL HAS ALREADY BOOKED, YOU FOOL!"
else
Booking.create!(name: params[:name], email: params[:email], event_id: #event.id)
end
end
end
Haven't really run this code, but it's just a simulation.