I am trying a an simple association which should work. I followed the tutorial at http://ruby.railstutorial.org/chapters/ and at chapter 10
Here what I have wrote down
model/customer
class Customer < ActiveRecord::Base
has_many :posts, dependent: :destroy
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
model/post
class Post < ActiveRecord::Base
belongs_to :customer
attr_accessible :description, :post_finish_at, :post_how, :post_location
controller/customers
class CustomersController < ApplicationController
before_filter :signed_in_customer, only: [:edit, :update]
before_filter :correct_customer, only: [:edit, :update]
def index
#customers = Customer.all
end
def show
#customer = Customer.find(params[:id])
#posts = #customer.posts
end ...
controller/post -- should be irrelevant since i am doing a partial
class PostsController < ApplicationController
# GET /posts
# GET /posts.json
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end
# GET /posts/1
# GET /posts/1.json
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #post }
end
end
# GET /posts/new
# GET /posts/new.json
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render json: #post, status: :created, location: #post }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.json
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.json { head :no_content }
end
end
end
view/customer/show.html.erb
<div class="posts">
<%= render 'posts/post'%>
</div>
view/post/_post.html.erb
<li>
<%= #posts.each do |post| %>
<%= post.title %>
<% end %>
</li>
Here what the output look like
[]
Why?
Thanks
It looks to me like you've got a couple things wrong. First, the partial (view/post/_post.html.erb) should be rendering a single post, not the whole collection of them. Second problem is that you're not passing anything to the partial.
There's a handy shorthand for rendering collections, where if you just render the collection, it will automatically look for a partial with the same name and render it for each model in the collection.
See: http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
So I think this should do what you want (I added <ul></ul> tags to make it an unordered list):
view/customer/show.html.erb
<div class="posts">
<ul>
<%= render #posts %>
</ul>
</div>
view/post/_post.html.erb
<li>
<%= post.title %>
</li>
It looks like customer doesn't have a posts association, but only an events association. I'd start there
Related
I am new to rails and I am creating a blog to look simliar to an Esquire website where they have the latest six posts at the top of the page lined up next to each other and then a little down the page they will have a large post by itself which continues the posts array so it would really be the 7th post and then a bit farther down the page you would have the next three posts 8-11 and so on.
I am having a difficult time trying to make the controller an array where I can call the first six items and then the 7th item separately later down the home page.
Posts Controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
#posts = Post.all.order('created_at DESC')
#topsix = #posts.take(6)
end
# GET /posts/new
def new
#post = current_user.posts.build
#categories = Category.all.map{|c| [ c.name, c.id ] }
end
# GET /posts/1/edit
def edit
#categories = Category.all.map{|c| [ c.name, c.id ] }
end
# POST /posts
# POST /posts.json
def create
#post = current_user.posts.build(post_params)
#post.category_id = params[:category_id]
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: "post was successfully created." }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
#post.category_id = params[:category_id]
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :excerpt, :create_date, :author, :body, :category_id, :image)
end
end
Home Controller:
class HomeController < ApplicationController
def index
#posts = Post.all.order('created_at DESC')
#topsix = #posts.take(6)
#first3 = #posts.order('created_at DESC').take(3)
#sidebar = #posts.take(3)
#first4 = #posts.take(4)
#first = #posts.take(1)
end
end
Where I am calling it on the Home page:
<div class="row no-gutters">
<% #topsix.select { |post| post > 6 } %>
<div class="col-md-2"><%= image_tag post.image.url(:large), class: "img-responsive"%>
<h6 class="small-title"><%= link_to post.title, post %></h6>
</div>
<% end %>
</div>
I think what you need is something like this:
#post1to6 = Post.all.order('created_at DESC').first(6) #top 6
#post7 = Post.all.order('created_at DESC').first(7).last #7th
num_post=Post.all.order('created_at DESC').count
#postRemainder = Post.all.order('created_at DESC').last(num_post-7) #Remainder
all_posts = Post.all.order('created_at DESC')
first_seven_posts = all_posts.take(7)
#first_six_posts = first_seven_posts.take(6)
#seventh_post = first_seven_posts.last
#other_posts = all_posts.where('id NOT IN (?)', first_seven_posts.map(&:id))
ive been having a problem now for 2 days, i followed many videos and tutorials on how to add comments to a post, and for everyone else it seemed to work smoothly.
I got 4 controllers, Users,Posts,Comments and Walls , basically this site is gonna be a facebook clone. So im displaying everything on the Wall index.html.erb
The error im getting is:
No route matches {:action=>"index", :controller=>"comments", :post_id=>nil} missing required keys: [:post_id]
Routes:
Rails.application.routes.draw do
devise_for :users
resources :uploads
resources :users
resources :posts do
resources :comments
end
resources :walls
root 'walls#index'
end
Comments-controller:
class CommentsController < ApplicationController
before_action :find_post
def index
#comments = Comment.all
end
def new
#post = Post.find(params[:post_id])
end
def create
#comment = #post.comments.create(params[:comment].permit(:content))
#comment.post_id = #post.id
#comment.user_id = current_user.id
#comment.save
# #comment = #post.comments.create(params[:comment].permit[:content])
# #comment.post_id = #post.id
respond_to do |format|
if #comment.save
format.html { redirect_to root_path }
# format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
# def comment_params
# params.require(:comment).permit(:content)
# end
def find_post
#post = Post.find(params[:post_id])
end
end
Posts-controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def new
#post = Post.new
#comment = Comment.new
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
#post.user_id = current_user.id
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
#post.user_id = current_user.id
#post.user = current_user
respond_to do |format|
if #post.save
format.html { redirect_to root_path }
# format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
#post.user_id = current_user.id
#post.save
respond_to do |format|
if #post.update(params[:post].permit(:image,:content,:youtube_url))
format.html { redirect_to root_path, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
format.json { respond_with_bip(#post) }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
format.json { respond_with_bip(#post) }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:content, :image, :username, :avatar, :youtube_url,:image_cache)
end
end
I am rendering the form in the index.html.erb for the wall controller index
<%= render "form" %>
And the form loop
views/walls/_form.html.erb
<div class="comments">
<%= form_for ([#post, #post.comments.build]) do |f| %>
byebug
<%= f.text_area :content, class: 'comments js-auto-size', id: 'alex2' ,:rows => 1 %>
<%= f.submit "Submit", class: "btn btn-default" %>
<% end %>
</div>
I dont understand why it cant find the post_id though :/
Since your comments is nested inside posts in routes, you have to pass post_id to the index in CommentsController
class CommentsController < ApplicationController
before_action :find_post
def index
#comments = #post.comments
end
end
# in view
<%= link_to "Comments", post_comments_path(#post) %>
Otherwise, you can define comments to be independent resources so you can do it without passing post_id
Rails.application.routes.draw do
resources :posts
resources :comments
end
sorry for this question but I'm struggling with this issue for hours now and can't find the answer anywhere.
Here is the thing, I have a rails app with "Reservation" and "Space" models with the following relations:
class Reservation < ActiveRecord::Base
belongs_to :space
belongs_to :user
end
class Space < ActiveRecord::Base
belongs_to :condo
has_many :reservations
end
When the user creates a new Reservation, in the form he gets to choose from a dropdown (f.select) the spaces available for him. The f.select in the form look like this:
<div class="field">
<%= #user_spaces = current_user.condo.spaces
f.select :space_id,
options_from_collection_for_select(#user_spaces, :id, :name), :prompt => "Select space"
%>
</div>
That select it supose to assign a value to the key "space_id" in the Reservation that is being created (column's table is created). But when I check the last reservation in Rails console, space_id value is "nil". What am I doing wrong?
Thank you very much for your help
Reservation controller file:
class ReservationsController < ApplicationController
before_action :set_reservation, only: [:show, :edit, :update, :destroy]
# GET /reservations
# GET /reservations.json
def index
#reservations = Reservation.all
end
# GET /reservations/1
# GET /reservations/1.json
def show
end
# GET /reservations/new
def new
#reservation = Reservation.new
end
# GET /reservations/1/edit
def edit
end
# POST /reservations
# POST /reservations.json
def create
#reservation = Reservation.new(reservation_params)
#user = current_user.id
#reservation.user_id = #user
respond_to do |format|
if #reservation.save
format.html { redirect_to #reservation, notice: 'Reservation was successfully created.' }
format.json { render :show, status: :created, location: #reservation }
else
format.html { render :new }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /reservations/1
# PATCH/PUT /reservations/1.json
def update
respond_to do |format|
if #reservation.update(reservation_params)
format.html { redirect_to #reservation, notice: 'Reservation was successfully updated.' }
format.json { render :show, status: :ok, location: #reservation }
else
format.html { render :edit }
format.json { render json: #reservation.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reservations/1
# DELETE /reservations/1.json
def destroy
#reservation.destroy
respond_to do |format|
format.html { redirect_to reservations_url, notice: 'Reservation was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_reservation
#reservation = Reservation.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def reservation_params
params.require(:reservation).permit(:eventdate)
end
end
Space controller file:
class SpacesController < ApplicationController
before_action :set_space, only: [:show, :edit, :update, :destroy]
# GET /spaces
# GET /spaces.json
def index
#spaces = Space.all
end
# GET /spaces/1
# GET /spaces/1.json
def show
end
# GET /spaces/new
def new
#space = Space.new
end
# GET /spaces/1/edit
def edit
end
# POST /spaces
# POST /spaces.json
def create
#space = Space.new(space_params)
respond_to do |format|
if #space.save
format.html { redirect_to #space, notice: 'Space was successfully created.' }
format.json { render :show, status: :created, location: #space }
else
format.html { render :new }
format.json { render json: #space.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /spaces/1
# PATCH/PUT /spaces/1.json
def update
respond_to do |format|
if #space.update(space_params)
format.html { redirect_to #space, notice: 'Space was successfully updated.' }
format.json { render :show, status: :ok, location: #space }
else
format.html { render :edit }
format.json { render json: #space.errors, status: :unprocessable_entity }
end
end
end
# DELETE /spaces/1
# DELETE /spaces/1.json
def destroy
#space.destroy
respond_to do |format|
format.html { redirect_to spaces_url, notice: 'Space was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_space
#space = Space.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def space_params
params.require(:space).permit(:name)
end
end
And full Reservation Form:
<%= form_for(#reservation) do |f| %>
<% if #reservation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#reservation.errors.count, "error") %> prohibited this reservation from being saved:</h2>
<ul>
<% #reservation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :eventdate %><br>
<%= f.date_select :eventdate %>
</div>
<div class="field">
<%= #user = current_user.condo.spaces
f.select :space_id,
options_from_collection_for_select(#user, :id, :name), :prompt => "Select space"
%>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
pretty sure you need to permit the space_id attribute in your strong params.
def reservation_params
params.require(:reservation).permit(:eventdate, :space_id)
end
whats happening is that when you go to create a reservation, youre passing in set of params, that is the output of reservation_params
#reservation = Reservation.new(reservation_params)
if space_id is not being permitted in your strong params, then it will be nil when created.
if this is not the issue, can you post what params are getting to the server, and what the output of reservation_params are.
I'm having a hard time implementing a checkout process where once at the cart, user can checkout and have order shipped. Maybe I need an order model and transaction controller?
I'm just not sure how to set those up. Currently the cart works and can be cleared as well as have items be added, its just I'm not sure how to implement a checkout and order system.
Idea is: User at cart clicks the checkout button, then is taken to checkout where he/she can input payment information, then taken back to products page. Issue is I'm not sure again how to connect the cart to the checkout and payment process into one simple easy system.
Any help would be appreciated, I'm still very new at this. Thank you.
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
flash[:notice] = 'added to cart'
end
def clearCart
session[:cart] = nil
redirect_to :action => :index
flash[:notice] = 'cart cleared'
end
def index
if session[:cart] then
#cart = session[:cart]
else
#cart = {}
end
end
end
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
def index
#products = Product.all
end
def show
end
def new
#product = Product.new
end
def edit
end
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_product
#product = Product.find(params[:id])
end
def product_params
params.require(:product).permit(:title, :description, :price, :category, :subcategory)
end
end
class Product < ActiveRecord::Base
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
views/cart/index.html.erb
<h1>Your Cart</h1>
<% if #cart.empty? %>
<p> Your cart is currently empty</p>
<% else %>
<%= link_to 'Empty your Cart', cart_clear_path %>
<br><br>
<% end %>
<% total = 0 %>
<ul>
<% #cart.each do | id, quantity | %>
<% product = Product.find_by_id(id) %>
<li>
<%= link_to product.title, product %>
<p><%= product.description %></p>
<p><%= number_to_currency product.price %></p>
<p>Quantity: <%= quantity %></p>
</li>
<% total += quantity * product.price %>
<% end %>
<p><b><%= number_to_currency total, :unit => '$' %> </b></p>
</ul>
What I've tried below
order.rb
class Order < ActiveRecord::Base
belongs_to :cart
end
cart.rb
class Cart < ActiveRecord::Base
has_many :line_items
has_one :order
end
Orders_Controller.rb
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
# GET /orders
# GET /orders.json
def index
#orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
#order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(order_params)
respond_to do |format|
if #order.save
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render :show, status: :created, location: #order }
else
format.html { render :new }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if #order.update(order_params)
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { render :show, status: :ok, location: #order }
else
format.html { render :edit }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order.destroy
respond_to do |format|
format.html { redirect_to orders_url, notice: 'Order was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
#order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:new, :cart_id, :ip_address, :first_name, :last_name, :user_id)
end
end
added Checkout to views/cart/index.html.erb
<%= link_to "Checkout", new_order_path, class: "btn btn-primary" %>
What do I do after this?
you've used a local variable product, not the controller attribute #product. (just add the '#' sign)
my advise to you is to use a gem like shoppe,
you can see example here (demo)
you can also navigate through the models of the gem to see how they did it, maybe it will give you a clear perspective of writing an e-commerce solution.
I am stuck on a problem and i would love a hand! I got the polymorphic association from railscast #154
So far I have gotten the comment model working splendidly. However I want to create a rating model as well that I can then add js to make pretty.
Looked at every other tutorial/stackoverflows I could find. None of them show how to work with multiple polymorphic associations in a controller.
I tried to duplicate the code for the article_controller but I am not sure how to do that for both models. So far my attempts have been unsuccessful. The partial form has the proper name, it is _ratings.html.erb
My Error:
Missing partial ratings/ratings with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in:
* "/code/jimbo/bigdog/app/views"
* "/home/user/.rvm/gems/ruby-2.0.0-p247#lulla-core/gems/kaminari-0.14.1/app/views"
* "/home/user/.rvm/gems/ruby-2.0.0-p247#lulla-core/gems/devise-3.1.1/app/views"
My Models:
class Rating
include Mongoid::Document
include Mongoid::MultiParameterAttributes
field :value, type: Integer, default: "0"
belongs_to :rateable, polymorphic: true
end
My Controllers:
class RatingsController < ApplicationController
before_filter :load_rateable
def index
#ratings = #rateable.rating
end
def show
#rating = #rateable.ratings.find(params[:id])
respond_to do |format|
format.html # show.html.erb
end
end
def new
#rating = #rateable.rating.new
end
def create
#rating = #rateable.rating.new(params[:rating])
if #rating.save
redirect_to #rateable, notice: "Rating created."
else
render :new
end
end
private
def load_rateable
resource, id = request.path.split('/')[1, 2]
#rateable = resource.singularize.classify.constantize.find(id)
end
# def load_commentable
# klass = [Article, Photo, Event].detect { |c| params["#{c.name.underscore}_id"] }
# #rateable = klass.find(params["#{klass.name.underscore}_id"])
# end
end
Article Controller
class ArticlesController < ApplicationController
# GET /articles
# GET /articles.json
def index
#articles = Article.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #articles }
end
end
# GET /articles/1
# GET /articles/1.json
def show
#article = Article.find(params[:id])
#commentable = #article
#comments = #commentable.comments
#comment = Comment.new
respond_to do |format|
format.html # show.html.erb
format.json { render json: #article }
end
end
# GET /articles/new
# GET /articles/new.json
def new
#article = Article.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #article }
end
end
# GET /articles/1/edit
def edit
#article = Article.find(params[:id])
end
# POST /articles
# POST /articles.json
def create
#article = Article.new(params[:article])
respond_to do |format|
if #article.save
format.html { redirect_to #article, notice: 'Article was successfully created.' }
format.json { render json: #article, status: :created, location: #article }
else
format.html { render action: "new" }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
# PUT /articles/1
# PUT /articles/1.json
def update
#article = Article.find(params[:id])
respond_to do |format|
if #article.update_attributes(params[:article])
format.html { redirect_to #article, notice: 'Article was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
# DELETE /articles/1
# DELETE /articles/1.json
def destroy
#article = Article.find(params[:id])
#article.destroy
respond_to do |format|
format.html { redirect_to articles_url }
format.json { head :no_content }
end
end
end
My View:
show.html (article)
<%= render "comments/comments" %>
<%= render "comments/form" %>
<%= render "ratings/ratings" %>
<%= render "ratings/form" %>
Routes:
resources :articles do
resources :comments
resources :ratings
end