I have been trying to build an app offering discounted vacation trips such that: (1) a user(travel agent) can compose a trip by combining hotels (hotel chains) and cities (2) a user(regular user) can review hotels and cities, s/he has already visited. (3) another user can evaluate how good the deal is with respect to the country and hotel the travel agent will have him/her stay.
The models look like this
class User < ActiveRecord::Base has_many :trips has_many :reviews end
class Trip < ActiveRecord::Base belongs_to :user belongs_to :hotel belongs_to :city end
class Hotel < ActiveRecord::Base belongs_to :city has_many :reviews, as: :reviewable end
class City < ActiveRecord::Base has_many :hotels has_many :reviews, as: :reviewabel end
class Review < ActiveRecord::Base belongs_to :user belongs_to :reviewable, polymorphic: true end
The problem is I can figure out how to create the controllers for Hotel and City because they are only created in the context of a makeshift trip. I checked the rails casts on nested forms and the use of accepts_nested_attributes_for
but I can't seem to get it right.
Note: the reason why I separated the hotels and the cities is to be able to retrieve the reviews independently. Such that Say I enjoyed my stay at the Four Seasons in Toronto but not the one in NY. - because of the cities/hotels (=> accommodating the case where I didn't enjoy it because the hotel was crap and the one where I didn't because the city was)
Note 2: I understand it doesn't make much sense to seperate hotels and cities in this example - I made a mistake in self-appointing the tutorial. But the problem has been haunting me, what if it was an delivery order instead with entree/meal/dinner instead of hotels and cities, or restaurant chains and neighborhoods.
Any help is appreciated. Thank you
Edit
Edited after Settheline's comment.
I mean the create actions for cities and hotels only exist in the context of a Trip create action. Trip has 2 attributes: title & description: It's only then that I “log” the itinerary. Here's what my controllers look like to give you a better idea
class TripsController < ApplicationController
before_action :signed_in_user
def show
@trip = Trip.find(params[:id])
end
def index
@trips = current_user.Trip.all
end
def new
@trip = Trip.new
end
def create
# @trip = Trip.new(trip_params)
@trip = current_user.trips.build(trip_params)
if @trip.save
flash[:success] = "Your trip was successfully published!"
redirect_to @trip
else
render 'new'
end
end
def edit
end
def update
if @trip.update_attributes(trip_params)
flash[:success] = "Trip was updated"
redirect_to @trip
else
render 'edit'
end
end
def destroy
Trip.find(params[:id]).destroy
flash[:success] = "trip was deleted. Thank you"
redirect_to @user #root_url
end
private
def trip_params
params.require(:trip).permit(:title, :description)
end
end
class CitiesController < ApplicationController
before_action :signed_in_user
def create
@city = City.new(city_params)
if @city.save
# flash[:success] = ""
else
render 'new'
end
end
# def destroy
# City.find(params[:id]).destroy
# flash[:success] = “City was deleted."
# redirect_to root_url
# end
private
def city_params
params.require(:city).permit(:name, :province, :country)
end
end
class HotelsController < ApplicationController
before_action :signed_in_user
def create
#similar to city
end
def destroy
#similar to city
end
private
def hotel_params
params.require(:hotel).permit(:name, :address,
:management_contact,
:city_id)
end
end
And here's the problem: I want to have/add create forms within the trip one in
sample_app/app/views/trips/new.html.erb
<% provide(:title, 'New Trip') %>
<h1>New Trip</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(@trip) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_field :title, placeholder: "Type in a title" %>
<%= f.text_field :description, placeholder: "Any additional info." %>
<%= f.submit "Publish", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
accepts_nested_attributes_for
allows you to save attributes on associations. Although you do have associations in your models it doesn't necessarily mean that you need to use accepts_nested_attributes_for
. It depends on how the code flows through your controllers.
For example, you would probably want to allow your users to view their trips and reviews. First you'll need a method to get the current user:
users_controller.rb
class ApplicationController < ActionController::Base
def current_user
@current_user ||= User.find(session[:user_id])
end
end
This method will be inherited by all of your controllers and allow them to get the current user. (There are many solutions out there for getting the current user, this is definitely not a good solution but it is OK for demonstration purposes).
Trips & Reviews
Now you can create some controllers for the current user to view their trips and reviews:
trips_controller.rb
class TripsController < ApplicationController
def index
@trips = current_user.trips.all
end
end
reviews_controller.rb
class ReviewsController < ApplicationController
def index
@reviews = current_user.reviews.all
end
end
Now you have some controller actions displaying the trips/reviews for the current user. I think this example demonstrates how you can create your controllers and that accepts_nested_attributes_for
is not necessarily required.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.