I apologize that this is such a simplistic question, but I've been struggling with it for a while.
I have two related models - Tour & Reservation. "Tour" has a "days" attribute. I want to list the days in a select tag for the user to choose from in my "Reservation" view
I thought this might work:
(Reservations controller) #tour_days = Tour.where(:days => params[:days])
(Reservations #new) = f.select :days, #tours_days
However, I'm receiving the error undefined methoddays' `
class Reservation < ActiveRecord::Base
belongs_to :tour
end
class Tour < ActiveRecord::Base
has_many :reservations
end
.
class ReservationsController < ApplicationController
def index
end
def new
#reservation = Reservation.new
#tour = Tour.find(params[:tour_id])
#tour_days = Tour.where(:days => params[:days])
end
def create
#tour = Tour.find(params[:tour_id])
if #reservation.update_attribute(:t_shirt, params[:t_shirt]) == true || #reservation.update_attribute(:hat, params[:hat]) == true
#tour.amount = #tour.amount + 15
else
#tour.amount = #tour.amount
end
#reservation = Reservation.new(reservation_params)
if #reservation.save
Stripe.api_key = ENV["STRIPE_SECRET_KEY"]
Stripe::Charge.create(
:amount => #tour.amount, # amount in cents, again
:currency => "usd",
:card => params[:stripeToken]
)
flash[:success] = "Your reservation has been booked for #{#reservation.passengers} person(s). Please save this info."
redirect_to new_tour_reservation_path(#tour)
else
render 'new'
end
end
private
def reservation_params
params.require(:reservation).permit(:passengers, :t_shirt, :hat)
end
end
.
class ToursController < ApplicationController
def index
#tours = Tour.all
end
def new
#tour = Tour.new
end
def create
#tour = Tour.new(tours_params)
if #tour.save
flash[:success] = "Tour #{#tour.name} has been successfully added."
redirect_to new_tour_path
else
flash[:error] = "The tour #{#tour.name} was not successfully saved. Please try again"
render 'new'
end
end
def show
#tour = Tour.find_by(id: params[:id])
#reservation = Reservation.new
end
def edit
#tour = Tour.find_by(id: params[:id])
end
def update
#tour = Tour.find_by(id: params[:id])
if #tour.update_attributes(tours_params)
flash[:success] = "#{#tour.name} has been successfully updated."
redirect_to tours_path
else
flash[:error] = "#{#tour.name} has not been updated. Please try again."
render 'edit'
end
end
def delete
#tour = Tour.find_by(id: params[:id])
end
def destroy
#tour = Tour.find_by(id: params[:id])
if #tour.destroy
flash[:success] = "The #{#tour.name} has been successfully deleted."
redirect_to tours_path
else
flash[:error] = "The #{#tour.name} has not been deleted. Please try again."
render 'edit'
end
end
private
def tours_params
params.require(:tour).permit(:name, :amount, :days)
end
end
.
= bootstrap_form_for([:tour, #reservation], html: { class: 'form-horizontal', id: 'payment-form'}) do |f|
= f.alert_message 'Please fix the errors below:'
= f.select :passengers, options_for_select( (1..10).map { |n| n %1 == 0 ? n.to_i : n } )
= f.select :days, #tours_days
%fieldset.credit_card
%span.payment-errors
.control-group
= label_tag :card_number, 'Credit card number:', class: 'control-label'
.controls
= text_field_tag :card_number, nil, name: nil, class: 'span3', data: {stripe: 'number'}
.control-group
= label_tag :security_code, 'Security code:', class: 'control-label'
.controls
= text_field_tag :security_code, nil, name: nil, class: 'span3', data: {stripe: 'cvc'}
.control-group
= label_tag :exp_date, 'Expiration:', class: 'control-label'
.controls
= select_month(Date.today, {add_month_numbers: true}, class: 'span2', data: {stripe: 'exp-month'})
= select_year(Date.today.year, {start_year: Date.today.year, end_year: Date.today.year + 4}, class: 'span1', data: {stripe: 'exp-year'})
%fieldset.actions.control-group
.controls
= f.submit 'Sign up'
consider using accepts_nested_attributes_for
Create another model to encapsulate the days. Then associate it with the Reservation model.
class Reservation < ActiveRecord::Base
belongs_to :tour
has_and_belongs_to_many :days
accepts_nested_attributes_for :days, allow_destroy: true
end
class Day < ActiveRecord::Base
has_and_belongs_to_many :reservations
end
The Day model will have one attribute: name which will hold the names of the seven days
class ReservationsController < ApplicationController
def create
#reservation = Reservation.new(reservation_params)
if #reservation.save
redirect_to #save
else
render :new
end
end
private
#add the `days_attributes` to the `reservations_params`
def reservation_params
params.require(:reservation).permit(:passengers, :t_shirt, :hat, days_attributes[:id, name])
end
end
then in new.html.erb when you are creating reservations, you can get a drop down to select specific days. you can do something like:
f.select :days
if you opt to use nested_forms, you'd have to use boostrap_nested_form_for as the documentation suggests.
Related
I have an application that allows a user to send a message to other users. I have two user types defined as enums in user rb- teacher and student:
enum access_level: [:student, :teacher]
I am wondering how to get the desired recipients to appear in a list in the view (below) so that a teacher can only send to students or the other way round.
In my messages controller I have:
class MessagesController < ApplicationController
before_action :authenticate_user!
def new
#chosen_recipient = User.find_by(id: params[:to].to_i) if params[:to]
end
def create
recipients = User.where(id: params['recipients'])
conversation = current_user.send_message(recipients, params[:message][:body], params[:message][:subject]).conversation
flash[:success] = "Message has been sent!"
redirect_to conversation_path(conversation)
end
end
And my conversations controller:
class ConversationsController < ApplicationController
before_action :authenticate_user!
before_action :get_mailbox
before_action :get_conversation, except: [:index, :empty_trash]
before_action :get_box, only: [:index]
def index
if #box.eql? "inbox"
#conversations = #mailbox.inbox
elsif #box.eql? "sent"
#conversations = #mailbox.sentbox
else
#conversations = #mailbox.trash
end
#conversations = #conversations.paginate(page: params[:page], per_page: 10)
end
def show
end
def mark_as_read
#conversation.mark_as_read(current_user)
flash[:success] = 'The conversation was marked as read.'
redirect_to conversations_path
end
def reply
current_user.reply_to_conversation(#conversation, params[:body])
flash[:success] = 'Reply sent'
redirect_to conversation_path(#conversation)
end
def destroy
#conversation.move_to_trash(current_user)
flash[:success] = 'The conversation was moved to trash.'
redirect_to conversations_path
end
def restore
#conversation.untrash(current_user)
flash[:success] = 'The conversation was restored.'
redirect_to conversations_path
end
def empty_trash
#mailbox.trash.each do |conversation|
conversation.receipts_for(current_user).update_all(deleted: true)
end
flash[:success] = 'Your trash was cleaned!'
redirect_to conversations_path
end
private
def get_mailbox
#mailbox ||= current_user.mailbox
end
def get_conversation
#conversation ||= #mailbox.conversations.find(params[:id])
end
def get_box
if params[:box].blank? or !["inbox","sent","trash"].include?(params[:box])
params[:box] = 'inbox'
end
#box = params[:box]
end
end
My view (messages/_form.html.erb):
<%= form_tag messages_path, method: :post do %>
<div class="form-group">
<%= label_tag 'message[subject]', 'Subject' %>
<%= text_field_tag 'message[subject]', nil, class: 'form-control', required: true %>
</div>
<div class="form-group">
<%= label_tag 'message[body]', 'Message' %>
<%= text_area_tag 'message[body]', nil, cols: 3, class: 'form-control', required: true %>
</div>
<div class="form-group">
<%= label_tag 'recipients', 'Choose recipients' %>
<%= select_tag 'recipients', recipients_options(#chosen_recipient), multiple: true, class: 'form-control chosen-it' %>
</div>
<%= submit_tag 'Send', class: 'btn btn-primary' %>
<% end %>
How would I get the list to appear based on the enum attribute associated with the user? A teacher could only see students for example.
Appreciate any guidance. Thanks.
Here are the methods given by the enum,
class User < ActiveRecord::Base
enum access_level: [ :student, :teacher ]
end
user.student!
user.student? # => true
user.access_level # => "student"
user.teacher!
user.teacher? # => true
user.access_level # => "teacher"
So you can use,
def new
if params[:to].present?
render text: params and return false
#chosen_recipient = current_user.student? ? check_access_level('teacher') : check_access_level('student')
end
end
private
def check_access_level(access_level)
User.where(id: params[:to].to_i, access_level: access_level)
end
Try this,
def new
#chosen_recipient = current_user.student? (User.where(id: params[:to].to_i, access_level: 1)) : current_user.teacher? (User.where(id: params[:to].to_i, access_level: 0)) if params[:to]
end
Have you tried changing the method that generates the chosen recipients? In helpers/messages_helpers.rb change the method as follows:
User.teacher.each do |user|
s << "leave this the way it is"
end
You can also do as Navin suggested and just check if the current user is a teacher. I would just put a variable as follows
if user.teachers?
reciepients = User.all
else
reciepients = User.teachers?
end
Then we can do as follows:
recipients.each do |user|
s << "leave this the way it is"
end
Hope that points you in the right direction.
I'm building a store in Rails that has a specific sales model. I need to allow a user to add only 3 items to his order per 30 days. The 30 days counter should start upon adding the first order_item. Once 30 days expires, user would be able to add 3 orders. If 30 days didn't pass and for an example, user adds two order_items he would still be allowed to add one more order_item within 30 days. So as well if user tries to add more then 3 items to show an error message and disregard saving of the order_items to current_user's order.
I'm getting this error in my log right now:
ActionController::RoutingError (undefined local variable or method current_order' for OrderItemsController:Class): app/controllers/order_items_controller.rb:15:in <class:OrderItemsController>' app/controllers/order_items_controller.rb:1:in `<top (required)>''
Relevant codes:
order_items_controller.rb
class OrderItemsController < ApplicationController
def create
#item = OrderItem.new(order_item_params)
session[:order_id] = current_order.id
if #item.save
respond_to do |format|
format.js { flash[:notice] = "ORDER HAS BEEN CREATED." }
end
else
redirect_to root_path
end
end
#order = current_order
#order_item = #order.order_items.new(order_item_params)
#order.user_id = current_user.id
#order.save
session[:order_id] = #order.id
end
private
def order_item_params
base_params = params.require(:order_item)
.permit(:quantity, :product_id, :user_id)
base_params.merge(order: current_order)
end
order_item.rb
class OrderItem < ActiveRecord::Base
belongs_to :product
belongs_to :order
validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0 }
validate :product_present
validate :order_present
validate :only_3_items_in_30_days
before_save :finalize
def unit_price
if persisted?
self[:unit_price]
else
product.price
end
end
def total_price
unit_price * quantity
end
private
def product_present
if product.nil?
errors.add(:product, "is not valid or is not active.")
end
end
def order_present
if order.nil?
errors.add(:order, "is not a valid order.")
end
end
def finalize
self[:unit_price] = unit_price
self[:total_price] = quantity * self[:unit_price]
end
def only_3_items_in_30_days
now = Date.new
days_since_first = now - order.first_item_added_at
if order.order_items.count > 2 && days_since_first < 30
errors.add(:base, 'only 3 items in 30 days are allowed')
end
true # this is to make sure the validation chain is not broken in case the check fails
end
end
And form that is being submitted:
<%= form_for OrderItem.new, html: {class: "add-to-cart"}, remote: true do |f| %>
<div class="input-group">
<%= f.hidden_field :quantity, value: 1, min: 1 %>
<div class="input-group-btn">
<%= f.hidden_field :product_id, value: product.id %>
<%= f.submit "Add to Cart", data: { confirm: 'Are you sure that you want to order this item for current month?'}, class: "btn btn-default black-background white" %>
</div>
</div>
<% end %>
</div>
Where are you setting your current_order?
class OrderItemsController < ApplicationController
def create
#item = OrderItem.new(order_item_params)
session[:order_id] = current_order.id
if #item.save
respond_to do |format|
format.js { flash[:notice] = "ORDER HAS BEEN CREATED." }
end
else
redirect_to root_path
end
end
# I have no idea of what this method ought to accomplish could you try to explain? but this is the immediate cause of the error. There could be others though.
def method_wrapper
#order = current_order
#order_item = #order.order_items.new(order_item_params)
#order.user_id = current_user.id
#order.save
session[:order_id] = #order.id
end
private
def order_item_params
base_params = params.require(:order_item)
.permit(:quantity, :product_id, :user_id)
base_params.merge(order: current_order)
end
end
So I am working on an assignment at the moment, where I am trying to display favorited posts. I currently have the favorited post displayed, but when I click it, it doesn't doesn't redirect me to anywhere.
Here is the code I currently have:
User#show where I am currently trying to display the favorited posts:
<div class="row">
<div class="col-md-8">
<div class="media">
<br />
<% avatar_url = #user.avatar_url(128) %>
<% if avatar_url %>
<div class="media-left">
<%= image_tag avatar_url, class: 'media-object' %>
</div>
<% end %>
<div class="media-body">
<h2 class="media-heading"><%= #user.name %></h2>
<small>
<%= pluralize(#user.posts.count, 'post') %>,
<%= pluralize(#user.comments.count, 'comment') %>
</small>
</div>
</div>
</div>
</div>
<h2>Posts</h2>
<%= posts_exists? %>
<%= render #user.posts %>
<h2>Comments</h2>
<%= comments_exists? %>
<%= render #user.comments %>
<h2>Favorites</h2>
<% #posts.each do |post| %>
<%= render partial: 'votes/voter', locals: { post: post } %>
<%= link_to post.title, topic_post_path(#topic, post) %>
<%= image_tag current_user.avatar_url(48), class: "gravatar" %>
<%= post.comments.count %> Comments
<% end %>
The error is occuring on the following line:
<%= link_to post.title, topic_post_path(#topic, post) %>
Here is the output from the error:
ActionView::Template::Error (No route matches {:action=>"show", :controller=>"posts", :id=>"54", :topic_id=>nil} missing required keys: [:topic_id]):
29: <h2>Favorites</h2>
30: <% #posts.each do |post| %>
31: <%= render partial: 'votes/voter', locals: { post: post } %>
32: <%= link_to post.title, topic_post_path(#topic, post) %>
33: <%= image_tag current_user.avatar_url(48), class: "gravatar" %>
34: <%= post.comments.count %> Comments
35: <% end %>
app/views/users/show.html.erb:32:in `block in _app_views_users_show_html_erb__1919900632491741904_70127642538380'
app/views/users/show.html.erb:30:in `_app_views_users_show_html_erb__1919900632491741904_70127642538380'
Obviously Topid.id is nil, but I can't figure out why. I'm going to provide you with everything I think you could need? I know this is probably a simple nooby issue, but I've been stuck on it for nearly an entire day already.
Here is my User#Controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new
#user.name = params[:user][:name]
#user.email = params[:user][:email]
#user.password = params[:user][:password]
#user.password_confirmation = params[:user][:password_confirmation]
if #user.save
flash[:notice] = "Welcome to Bloccit #{#user.name}!"
create_session(#user)
redirect_to root_path
else
flash[:error] = "There was an error creating your account. Please try again."
render :new
end
end
def show
#user = User.find(params[:id])
#posts = #user.posts.visible_to(current_user)
#posts = Post.joins(:favorites).where('favorites.user_id = ?', #user.id)
#favorites = current_user.favorites
end
end
Here is my Post#Controller:
class PostsController < ApplicationController
before_action :require_sign_in, except: :show
before_action :authorize_user, except: [:show, :new, :create]
def show
#post = Post.find(params[:id])
end
def new
#topic = Topic.find(params[:topic_id])
#post = Post.new
end
def create
#topic = Topic.find(params[:topic_id])
#post = #topic.posts.build(post_params)
#post.user = current_user
if #post.save
#post.labels = Label.update_labels(params[:post][:labels])
flash[:notice] = "Post was saved."
redirect_to [#topic, #post]
else
flash[:error] = "There was an error saving the post. Please try again."
render :new
end
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
#post.assign_attributes(post_params)
if #post.save
#post.labels = Label.update_labels(params[:post][:labels])
flash[:notice] = "Post was updated."
redirect_to [#post.topic, #post]
else
flash[:error] = "There was an error saving the post. Please try again."
render :edit
end
end
def destroy
#post = Post.find(params[:id])
if #post.destroy
flash[:notice] = "\"#{#post.title}\" was deleted successfully."
redirect_to #post.topic
else
flash[:error] = "There was an error deleting the post."
render :show
end
end
private
def post_params
params.require(:post).permit(:title, :body)
end
def authorize_user
post = Post.find(params[:id])
unless current_user == post.user || current_user.admin?
flash[:error] = "You must be an admin to do that."
redirect_to [post.topic, post]
end
end
end
Here is my Topics#Controller:
class TopicsController < ApplicationController
before_action :require_sign_in, except: [:index, :show]
before_action :authorize_user, except: [:index, :show]
def index
#topics = Topic.all
end
def show
#topic = Topic.find(params[:id])
end
def new
#topic = Topic.new
end
def create
#topic = Topic.new(topic_params)
if #topic.save
#topic.labels = Label.update_labels(params[:topic][:labels])
redirect_to #topic, notice: "Topic was saved successfully."
else
flash[:error] = "Error creating topic. Please try again."
render :new
end
end
def edit
#topic = Topic.find(params[:id])
end
def update
#topic = Topic.find(params[:id])
#topic.assign_attributes(topic_params)
if #topic.save
#topic.labels = Label.update_labels(params[:topic][:labels])
flash[:notice] = "Topic was updated."
redirect_to #topic
else
flash[:error] = "Error saving topic. Please try again."
render :edit
end
end
def destroy
#topic = Topic.find(params[:id])
if #topic.destroy
flash[:notice] = "\"#{#topic.name}\" was deleted successfully."
redirect_to action: :index
else
flash[:error] = "There was an error deleting the topic."
render :show
end
end
private
def topic_params
params.require(:topic).permit(:name, :description, :public)
end
def authorize_user
unless current_user.admin?
flash[:error] = "You must be an admin to do that."
redirect_to topics_path
end
end
end
Here is my User Model:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
has_many :votes, dependent: :destroy
has_many :favorites, dependent: :destroy
before_save { self.email = email.downcase }
before_save { self.role ||= :member }
EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :name, length: { minimum: 1, maximum: 100 }, presence: true
validates :password, presence: true, length: { minimum: 6 }, if: "password_digest.nil?"
validates :password, length: { minimum: 6 }, allow_blank: true
validates :email,
presence: true,
uniqueness: { case_sensitive: false },
length: { minimum: 3, maximum: 100 },
format: { with: EMAIL_REGEX }
has_secure_password
enum role: [:member, :admin]
def favorite_for(post)
favorites.where(post_id: post.id).first
end
def avatar_url(size)
gravatar_id = Digest::MD5::hexdigest(self.email).downcase
"http://gravatar.com/avatar/#{gravatar_id}.png?s=#{size}"
end
end
Here is my Topic Model:
class Topic < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :labelings, as: :labelable
has_many :labels, through: :labelings
end
Here is my Post Model:
class Post < ActiveRecord::Base
belongs_to :topic
belongs_to :user
has_many :comments, dependent: :destroy
has_many :votes, dependent: :destroy
has_many :labelings, as: :labelable
has_many :labels, through: :labelings
has_many :favorites, dependent: :destroy
default_scope { order('rank DESC') }
scope :visible_to, -> (user) { user ? all : joins(:topic).where('topics.public' => true) }
validates :title, length: { minimum: 5 }, presence: true
validates :body, length: { minimum: 20 }, presence: true
validates :topic, presence: true
validates :user, presence: true
def up_votes
votes.where(value: 1).count
end
def down_votes
votes.where(value: -1).count
end
def points
votes.sum(:value)
end
def update_rank
age_in_days = (created_at - Time.new(1970,1,1)) / 1.day.seconds
new_rank = points + age_in_days
update_attribute(:rank, new_rank)
end
end
Any insight anyone could provide, I would be extremely grateful for. If you have the time to explain where I went wrong as well, that would be even more helpful.
User#show where I am currently trying to display the favorited posts
But you're not setting #topic in your User#show action. That's why it's nil.
def show
#user = User.find(params[:id])
#posts = #user.posts.visible_to(current_user)
#posts = Post.joins(:favorites).where('favorites.user_id = ?', #user.id)
#favorites = current_user.favorites
# your #topic object is not in here?
end
Since a post belongs_to a topic you could do something like this:
<%= link_to post.title, topic_post_path(post.topic, post) %>
how to insert parameter value manually from controller,
this my controller
def new
#new_post = Post.new(params[:title])
end
def create
#new_post = Post.new(new_post_params)
if #new_post.save
flash[:success] = 'Post created!'
redirect_to home_url
else
flash[:danger] = #new_post.errors.full_messages.to_sentence
redirect_to home_url
end
end
private
def new_post_params
params.require(:post).permit(
:title,
poster_id: current_user.id,
poster_name: current_user.name
)
end
my form view like this
form_for #new_post do |f|
f.text_area :title
end
tired using this method, poster_id and poster_name still blank
def new_post_params
params.require(:post).permit(
:title,
poster_id: current_user.id,
poster_name: current_user.name
)
end
Try this
params.require(:post).permit(:title).merge(
{
poster_id: current_user.id,
poster_name: current_user.name
}
)
def new_post_params
params[:post][:poster_id] = current_user.id
params[:post][:poster_name] = current_user.name
params.require(:post).permit(
:title,
:poster_id,
:poster_name
)
end
I'm working on an app to book different types of tours. I have 3 tables - 1) reservations 2) tours 3) join table (reservations_tours). I'm trying to pass the tour id to reservations, but keep getting this error:
Couldn't find Tour without an ID
app/controllers/reservations_controller.rb:12:in `create'
Reservations controller:
class ReservationsController < ApplicationController
def index
end
def new
#reservation = Reservation.new
#tour = Tour.find(params[:tour_id])
end
def create
#tour = Tour.find(params[:tour_id])
#reservation = Reservation.new(reservation_params)
##reservation.tour = #tour # associate #reservation with video
if #reservation.save
Stripe.api_key = ENV["STRIPE_SECRET_KEY"]
Stripe::Charge.create(
:amount => 9000, # amount in cents, again
:currency => "usd",
:card => params[:stripeToken] # Get the credit card details submitted by the form
)
flash[:success] = "Your reservation has been booked for #{#reservation.date} for #{#reservation.passengers} person(s). Please save this info."
redirect_to new_tour_path
else
render 'new'
end
end
private
def reservation_params
params.require(:reservation).permit(:date, :passengers)
end
end
Tours controller:
class ToursController < ApplicationController
def index
end
def new
#tour = Tour.new
end
def create
#tour = Tour.new(tours_params)
if #tour.save
flash[:success] = "Tour #{#tour.name} has been successfully added."
redirect_to new_tour_path
else
flash[:error] = "The tour #{#tour.name} was not successfully saved. Please try again"
render 'new'
end
end
def show
#tour = Tour.find_by(id: params[:id])
#reservation = Reservation.new
end
def edit
end
def update
end
private
def tours_params
params.require(:tour).permit(:name, :amount)
end
end
Reservations view (new)
= javascript_include_tag "https://js.stripe.com/v2/"
= javascript_include_tag 'payment'
:javascript
Stripe.setPublishableKey("#{ENV['STRIPE_PUBLISHABLE_KEY']}");
.container
.row
.col-md-9
%h2= #tour.name
.col-md-3
%p= #tour.amount
= bootstrap_form_for(#reservation, html: { class: 'form-horizontal', id: 'payment-form'}) do |f|
= f.alert_message 'Please fix the errors below:'
= f.text_field :date
= f.text_field :passengers
%fieldset.credit_card
%span.payment-errors
.control-group
= label_tag :card_number, 'Credit card number:', class: 'control-label'
.controls
= text_field_tag :card_number, nil, name: nil, class: 'span3', data: {stripe: 'number'}
.control-group
= label_tag :security_code, 'Security code:', class: 'control-label'
.controls
= text_field_tag :security_code, nil, name: nil, class: 'span3', data: {stripe: 'cvc'}
.control-group
= label_tag :exp_date, 'Expiration:', class: 'control-label'
.controls
= select_month(Date.today, {add_month_numbers: true}, class: 'span2', data: {stripe: 'exp-month'})
= select_year(Date.today.year, {start_year: Date.today.year, end_year: Date.today.year + 4}, class: 'span1', data: {stripe: 'exp-year'})
%fieldset.actions.control-group
.controls
= f.submit 'Sign up'
Reservation model:
class Reservation < ActiveRecord::Base
has_many :reservations_tours, foreign_key: 'reservation_id'
has_many :tours, through: :reservations_tours
end
Tour model
class Tour < ActiveRecord::Base
has_many :reservations_tours, foreign_key: 'tour_id'
has_many :reservations, through: :reservations_tours
end
Join table
class ReservationsTours < ActiveRecord::Base
belongs_to :reservation, foreign_key: 'reservation_id'
belongs_to :tour, foreign_key: 'tour_id'
end
Routes:
Rails.application.routes.draw do
resources :reservations, only: [:new, :create]
resources :tours
end
You are trying to create a non existing relation. You have two basic options to create a relation in rails:
Provide a dropdown with existing tours in the reservations form
f.collection_select(:tour_id, Tour.all, :id, :name)
it will become available in the params[:reservation] array. You will have to permit the tour_id param in reservation_params
make a nested resource for reservations in config/routes.rb.
resources :tours do
resources :reservations
end
which will give you a POST url like /tours/:tour_id/reservations and provide you with params[:tour_id]