FLATPICKR SUBMIT? - Trying to make a booking button but not working - ruby-on-rails

the thing, that i tried a lot of stuff is is not working at all, somehow i am having this kind of error in my terminal, when i do my post request from my form:
20:21:01 web.1 | Started POST "/bookings" for ::1 at 2023-02-19 20:21:01 +0100
20:21:01 web.1 | Processing by BookingsController#create as TURBO_STREAM
20:21:01 web.1 | Parameters: {"authenticity_token"=>"[FILTERED]", "booking"=>{"start_time"=>"2023-02-28", "end_time"=>"2023-03-08"}, "commit"=>"Schedule your appointment"}
20:21:01 web.1 | User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 3], ["LIMIT", 1]]
20:21:01 web.1 | Completed 404 Not Found in 4ms (ActiveRecord: 0.9ms | Allocations: 2628)
20:21:01 web.1 |
20:21:01 web.1 |
20:21:01 web.1 |
20:21:01 web.1 | ActiveRecord::RecordNotFound (Couldn't find Game without an ID):
20:21:01 web.1 |
20:21:01 web.1 | app/controllers/bookings_controller.rb:38:in `set_game'
20:21:01 web.1 | Started GET "/games/37" for ::1 at 2023-02-19 20:21:01 +0100
20:21:01 web.1 | Processing by GamesController#show as HTML
So I have a Games_controller User created with the devise, and a Bookings_controller. And in my show page, I see my bookings option, but somehow, when I click the submit button, nothing happend, and i got the error that I shared before, and I am not sure why. And the thing, that i dont understand is why i am not having any kind of flags like if my booking is not being saved at all, or if it saved i should have some kind of flag. So after a lot of consideration i decided to ask here.
Because I am definint my games_id in the form of my _show.html.erb. So if anyone has a solution for it will be great
GAMES_CONTROLLER
class GamesController < ApplicationController def home
authorize Game end
def index
#games = Game.all
#games = policy_scope(Game) end
def new
#game = Game.new
authorize #game end
def create
#game = Game.new(game_params)
#game.user = current_user
if #game.save
redirect_to game_path(#game) # later to be changed in game_path(#game) when we have a show
else
render :new, status: :unprocessable_entity
end
authorize #game end
def show
#game = Game.find(params[:id])
#booking = Booking.new(game: #game)
authorize #game end
def edit
#game = Game.find(params[:id])
authorize #game end
def update
#game = Game.find(params[:id])
if #game.update(game_params)
redirect_to game_path(#game)
else
render :new, status: :unprocessable_entity
end
authorize #game end
def destroy
#game = Game.find(params[:id])
#game.destroy
redirect_to games_path
authorize #game end
private
def game_params
params.require(:game).permit(:price, :title, :description, :photo) end end
BOOKING_CONTROLLER
class BookingsController < ApplicationController before_action :set_game, only: [:create] before_action :set_booking, only: [:show]
def index
authorize Booking
#bookings = policy_scope(Booking)
puts "Number of bookings: #{#bookings.count}" end
def show
authorize #booking end
def create
puts "Params: #{params.inspect}"
#booking = Booking.new(booking_params.merge(game: #game, user: current_user))
authorize #booking
if #booking.save
flash[:notice] = "Booking was successfully created."
redirect_to #booking
else
flash[:alert] = "There was an error creating the booking."
redirect_to #game
end
Rails.logger.debug "Params: #{params.inspect}"
Rails.logger.debug "Game: #{#game.inspect}"
Rails.logger.debug "Booking: #{#booking.inspect}"
Rails.logger.debug "Booking params: #{booking_params.inspect}"
Rails.logger.debug "Current user: #{current_user.inspect}" end
private
def set_game
#game = Game.find(params[:game_id])
puts #game.inspect end
def set_booking
#booking = Booking.find(params[:id]) end
def booking_params
params.require(:booking).permit(:start_date, :end_date, :game_id) end
def set_dates
self.start_date = start_date.to_date
self.end_date = end_date.to_date end
end
GAMES - SHOW.HTML.ERB
<%= render 'shared/navbar' %>
<h1>Show</h1> <h2><%= #game.title %></h2> <%= cl_image_tag #game.photo.key,
width: 400, height: 300, crop: :fill %> <p><%= #game.description %></p> <p><%= #game.price %></p> <p><% #game.categories.each do |category| %> <%= category.name %> <% end %> </p>
<p><%= link_to 'Edit game listing', edit_game_path(#game) if policy(#game).edit?%></p> <p><%= link_to 'Delete game listing', game_path(#game), data: { turbo_method: :delete, turbo_confirm: "Are you sure?" }if policy(#game).edit?%></p> <p><%= link_to 'Back to games', games_path %></p>
<h1>BOOKINGS</h1>
<%= render partial: 'bookings/show', locals: { booking: #booking } %>
BOOKING _SHOW.HTML.ERB
<%= simple_form_for #booking, data: { controller: 'flatpickr' } do |f| %> <%= f.hidden_field :game_id, value: #game.id %> <%= f.input :start_time, as: :string, input_html: { data: { flatpickr_target: "startTime" } } %> <%= f.input :end_time, as: :string, input_html: { data: { flatpickr_target: "endTime" } } %> <%= f.submit 'RENT THE GAME', class: 'btn btn-primary' %> <% end %>
<h1>Booking Details</h1> <p><strong>Start date:</strong> <%= #booking.start_date %></p> <p><strong>End date:</strong> <%= #booking.end_date %></p>
<h1>Here Come the calendar</h1> <%= render partial: 'bookings/calendar', locals: { bookings: #bookings } %>
BOOKING _CALENDAR.HTML.ERB
<div id='calendar'></div> <% if #bookings.present? %> <% #bookings.each do |booking| %>
<%= booking.inspect %><br> # Add this line <% end %> <% else %> No bookings to display. <% end %>
<script> document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
events: [
<% if #bookings %>
<% #bookings.each do |booking| %>
{
title: '<%= booking.game.title %>',
start: '<%= booking.start_date %>',
end: '<%= booking.end_date %>',
color: 'red'
},
<% end %>
<% end %>
]
});
calendar.render(); }); </script>
<html lang='en'> <head>
<meta charset='utf-8' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar#6.1.4/index.global.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth'
});
calendar.render();
});
</script> </head> <body>
<div id='calendar'></div> </body> </html>

Related

Ruby on Rails 5: Can't Save Record, Unpermitted Parameter for Has Many Through Record

Ruby on Rails 5, Simple Form
Product has many Specifications through ProductSpecs
in Product#Edit, I want to add new Specifications.
if Specifications.save successful, rerender Product. It rerenders products and flashes "success", but the new specification does not persist.
The log indicates unpermitted parameters-- not sure how to correct my product_parameters. I have tried { product_specs => [] } to no avail.
Any help would be greatly appreciated!
Log:
Started PATCH "/products/2" for 127.0.0.1 at 2019-03-07 14:44:24 +0800
Processing by ProductsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"f/wU9o1Fi8jXlTDCiJF93xMXFlaRH6sKx9+lNyg4ZGthVGkhPMrLwES/bEgeeHTHXdXaoolj67FOnGqqULtysg==", "product"=>{"name"=>"Notebooks", "description"=>"Handheld military and medical devices are built to operate in a variety of environments and also built to last.asdfasdfasdf", "category_id"=>"1", "product_spec"=>{"specification"=>{"name"=>"COLD", "low_value"=>"1", "high_value"=>"22", "unit"=>"volts"}}}, "commit"=>"Add New Spec", "id"=>"2"}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
Setting the product: Notebooks
#<Product id: 2, name: "Notebooks", description: "Handheld military and medical devices are built to...", picture: nil, created_at: "2019-02-20 06:43:20", updated_at: "2019-03-07 05:53:37", iconblack: "icons/products/icon_IPC_black.png", iconwhite: nil, iconyellow: nil, category_id: 1>Unpermitted parameter: product_spec
(0.1ms) begin transaction
Category Load (0.2ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
(0.1ms) commit transaction
SUPPOSEDLY UPDATING
Unpermitted parameter: product_spec
product parameters: <ActionController::Parameters {"name"=>"Notebooks", "description"=>"Handheld military and medical devices are built to operate in a variety of environments and also built to last.asdfasdfasdf", "category_id"=>"1"} permitted: true>Redirected to http://localhost:3000/products/2
Completed 302 Found in 7ms (ActiveRecord: 0.5ms)
Started GET "/products/2" for 127.0.0.1 at 2019-03-07 14:44:24 +0800
Processing by ProductsController#show as HTML
Products Controller:
class ProductsController < ApplicationController
# before_action :set_category, only: [:new, :create]
before_action :set_product, only: [:edit, :show, :update, :destroy]
def index
#products = Product.all
#categories = Category.all
#message = Message.new
#message.build_company
end
def new
#product = Product.new
#categories = Category.all
#message = Message.new
#message.build_company
#product.specifications.build
# setting product stuff for testing
#product.picture = "products/IPC_tablet.png"
#product.iconblack = "icons/products/icon_IPC_black.png"
end
def create
#message = Message.new
#message.build_company
#categories = Category.all
#product = Product.new(product_parameters)
#product.category_id = product_parameters[:category_id]
#product_spec = ProductSpec.new
#new_spec= Specification.new
if #product.save!
flash[:success] = "You have saved the #{#product.name} product"
redirect_to product_path(#product)
else
flash.now[:error] = "Product was not saved"
render "new"
end
end
def show
#product = Product.find(params[:id])
#categories = Category.all
#message = Message.new
#message.build_company
#product_specs = #product.product_specs
end
def edit
#message = Message.new
#message.build_company
#categories = Category.all
# To create a new specification through product spec
#product_spec = ProductSpec.new
#new_spec= Specification.new
#product_spec.product = #product
#product_spec.specification = #new_spec
end
def update
# puts "in update product, product parameters: #{product_parameters}"
# puts product_parameters
if #product.update(product_parameters)
flash[:success] = "You have updated the #{#product.name} product"
puts "SUPPOSEDLY UPDATING"
print "product parameters: #{product_parameters.inspect}"
redirect_to product_path(#product)
else
# puts "SUPPOSEDLY NOT UPDATING"
flash.now[:error] = "You have not updated #{#product.name}"
render :edit
end
end
private
def build_company
#message.build_company
end
def set_product
#product = Product.find(params[:id])
puts "Setting the product: #{#product.name}"
print #product.inspect
end
def find_category
#category = Category.find(params[:category_id])
end
def product_parameters
params.require(:product).permit(
:id,
:name,
:description,
:picture,
:category_id,
category: [
:id
],
product_specs: [
{:specification => [] } ]
)
end
end
Product Specs Controller:
class ProductSpecsController < ApplicationController
before_action :find_product, only: [:new, :create, :destroy, :set_product_spec]
before_action :set_product_spec, only: [:destroy, :show]
def new
#product_spec = ProductSpec.new(:product_id => params[:product_id])
end
def create
end
def destroy
#product = Product.find(params[:product_id])
if #product_spec.destroy
flash[:success] = "Product Specification Deleted"
redirect_to product_path(#product.id)
else
flash[:error] = "Oops! Something went wrong"
redirect_to product_path
end
end
private
def find_product
#product = Product.find(params[:product_id])
end
def set_specification
end
def set_product_spec
#product_spec = ProductSpec.find_by(params[:product_id])
end
end
Specifications Controller:
class SpecificationsController < ApplicationController
before_action :set_specification, only: [:edit, :show, :update, :destroy]
def new
end
def create
end
def destroy
end
private
def set_specification
#specification = Specification.find(params[:id])
end
end
Products#Edit Form/View:
<%= simple_form_for #product do |product| %>
<h4 class="product_name">
<%= product.input :name, placeholder: "Product Name" %>
</h4>
<div class="product_picture">
<%= image_tag("products/IPC_tablet.png") %>
</div>
<div class="product_description">
<strong>Description</strong>
<p class="font-size-12">
<%= product.input :description, label: false %>
</p>
<%= product.association :category, prompt: "Select Category" %>
</div>
<div class="product_specifications">
<strong>Specifications</strong>
<!-- RENDER THRU PRODUCT SPECS, EACH EXISTING SPECIFICATION -->
<% if #product_specs %>
<%= product.simple_fields_for :product_specs do |ps| %>
<%= ps.simple_fields_for :specification do |spec| %>
<div class="add_specification">
<div class="specification_fields">
<%= spec.input :name, label: false, input_html: { class: 'spec_input_name' }, placeholder: "Spec" %>
<%= spec.input :low_value, input_html: { class: 'spec_input_values' }, label: false, placeholder:"Lowest Value" %>
<%= spec.input :high_value, input_html: { class: 'spec_input_values' }, label: false, placeholder: "Highest Value" %>
<%= spec.input :unit, label: false, input_html: { class: 'spec_input_values' }, placeholder:"Unit" %>
<%= spec.button :submit, "Save Spec" %>
</div>
</div>
<% end %>
<% end %>
<div>
<strong>Add A New Specification</strong>
</div>
<% end %>
<!-- - - - - - ADD A NEW SPECIFICATION -->
<%= product.simple_fields_for #product_spec do |newps| %>
<%= newps.simple_fields_for #new_spec do |newspec| %>
<div class="add_specification">
<div class="specification_fields">
<%= newspec.input :name, label: false, input_html: { class: 'spec_input_name' }, placeholder: "Spec Name" %>
<%= newspec.input :low_value, label: false, input_html: { class: 'spec_input_values' }, placeholder: "Lowest Value" %>
<%= newspec.input :high_value, label: false, input_html: { class: 'spec_input_values' }, placeholder: "Highest Value" %>
<%= newspec.input :unit, label: false, input_html: { class: 'spec_input_values' }, placeholder: "Unit" %>
<%= newspec.button :submit, "Add New Spec" %>
<% end %>
</div>
<% end %>
</div>
<div class="product_admin_actions">
<%= product.button :submit, "Save This Product" %>
</div>
<% end %>
I think the problem about understanding how accepts_nested_attributes_for works in Rails. I'll try to explain it clearly.
the relation between the models also another important part. If we accept the realtion like: Product -> ProductSpec -> Specification solution must be like this.
# models/product.rb
class Product < ApplicationRecord
has_many :product_specs
accepts_nested_attributes_for :product_specs
end
# models/product_spec.rb
class ProductSpec < ApplicationRecord
has_many :specifications
accepts_nested_attributes_for :specifications
end
# controllers/products_controller.rb
class ProductsController < ApplicationController
...
def create
#proudct = Product.create(product_params)
end
private
def product_params
params.require(:product).permit(
:id,
:name,
:description,
:picture,
:category_id,
product_specs_attributes: [:id,
specifications_attributes: [:id, :name, :low_value, :high_value]
])
end
end
Your view fields looks correct.

ruby on rails best_in_place nomethoderror

i am getting an error with the best_in_place gem.
i want to edit my comments inside of the post show action since i render all comments there.
NoMethodError in Posts#show
Showing undefined method `erererer' for #<Comment:0x00007fc0ff1721c8>
comment view that i render in posts show page.
<!--<h3>there are <%#= pluralize(#comments.count, "comment") %></h3> -->
<% #comments.each do |comment| %>
<div class="media mb-5 ">
<% if comment.user.avatar.present? %>
<%= image_tag comment.user.avatar.url, class: 'rounded mr-3 d-flex', width: 42, height: 42%>
<% else %>
<%= random_avatar 42, "d-flex rounded mr-3"%>
<% end %>
<div class="media-body">
<div class="d-flex justify-content-between" />
<h5 class="mt-0"><a><%=link_to comment.user.username, user_path(comment.user) %></a></h5>
<p class="m-0 form-group">created at <%=time_ago_in_words(comment.created_at) %></p>
</div>
<%= best_in_place comment, comment.body, :as => :textarea %>
<% if current_user == comment.user %>
<span style="font-size: 15px;">
<%= link_to '', [comment.post, comment], method: :delete, data: {confirm: "sure?"}, class: ' btn btn-outline-danger btn-sm pull-right fa fa-trash-o' %>
<%= link_to '',edit_post_comment_path(comment.post, comment), class: 'btn btn-outline-warning btn-sm pull-right fa fa-pencil-square-o' %>
</span>
<% end %>
</div>
</div>
</section>
<%end%>
application.js
$(document).ready(function() {
/* Activating Best In Place */
$('.best_in_place').best_in_place();
});
comments_controller.rb
def update
if #comment.update(params[:comment].permit(:body))
format.html { redirect_to post_path(#post) }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { respond_with_bip(#comment) }
end
end
comment.rb
class Comment < ApplicationRecord
belongs_to :post
belongs_to :user
validates :body, presence: true
end
post.rb
class Post < ApplicationRecord
belongs_to :user
has_many :comments, dependent: :destroy
validates :title, presence: true, length: { minimum: 5 }
validates :body, presence: true, length: { minimum: 240 }
post.controller - add post controller code to question
class PostsController < ApplicationController
before_action :find_post, only: %i[destroy edit update comment_owner upvote downvote]
after_action :verify_authorized, only: [:edit, :update, :destroy, :create, :new]
layout '_app_nav'
def index
return redirect_to post_path(params[:post_id]) if params[:post_id]
return redirect_to user_path(params[:user_id]) if params[:user_id]
#post = Post.all.order('created_at DESC')
#posts = Post.all.order('created_at DESC')
#user = User.all
#posts = if params[:search]
else
Post.all.order('created_at DESC')
end
#comments = Comment.all
end
def new
#post = Post.new
end
def create
#post = current_user.posts.build(post_params)
authorize #post
if #post.save!
redirect_to #post
else
render 'new'
end
end
def show
#post = Post.find(params[:id])
#user = #post.user
#comments = Comment.where(post_id: #post).order('created_at DESC').paginate(:page => params[:page], :per_page => 5)
end
def edit
authorize #post
end
def update
authorize #post
if #post.update(post_params)
redirect_to #post, notice: 'updated.'
else
render :edit
end
end
end
def destroy
#post = Post.find(params[:id])
authorize #post
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :body, :user_id)
end
def find_post
#post = Post.find(params[:id])
end
UPDATE
This is the entire request that i get when trying to open posts#show
Started GET "/news/2" for 127.0.0.1 at 2018-07-30 03:12:49 +0200
(0.6ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by PostsController#show as HTML
Parameters: {"id"=>"2"}
Post Load (0.4ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 3], ["LIMIT", 1]]
Rendering posts/show.html.erb within layouts/_app_nav
Rendered comments/_form.html.erb (27.1ms)
Comment Load (0.9ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 2 ORDER BY created_at DESC LIMIT $1 OFFSET $2 [["LIMIT", 5], ["OFFSET", 0]]
CACHE User Load (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 3], ["LIMIT", 1]]
Rendered comments/_comment.html.erb (14.2ms)
Rendered posts/show.html.erb within layouts/_app_nav (442.2ms)
Completed 500 Internal Server Error in 509ms (ActiveRecord: 12.4ms)
ActionView::Template::Error (undefined method `erererer' for #<Comment:0x00007feba5717bc0>):
15:
16: <p class="m-0 form-group">created at <%=time_ago_in_words(comment.created_at) %></p>
17: </div>
18: <%= best_in_place comment, comment.body, :as => :textarea %>
19: <% if current_user == comment.user %>
20: <span style="font-size: 15px;">
21: <%= link_to '', [comment.post, comment], method: :delete, data: {confirm: "sure?"}, class: ' btn btn-outline-danger btn-sm pull-right fa fa-trash-o' %>
app/views/comments/_comment.html.erb:18:in `block in _app_views_comments__comment_html_erb___2232672375721569353_70325032812060'
app/views/comments/_comment.html.erb:5:in `_app_views_comments__comment_html_erb___2232672375721569353_70325032812060'
app/views/posts/show.html.erb:76:in `_app_views_posts_show_html_erb___2994099099531367002_70324990819000'
<%= best_in_place comment, comment.body, :as => :textarea %> should be <%= best_in_place comment, :body, :as => :textarea %>

Rails: Object saving in console but not within app

I know this must be a dumb error somewhere, but I've been going in circles trying to figure out why my objects only save within the console, and not in the app itself.
Anyone have an idea?
Here's the code:
Controller:
class JobsController < ApplicationController
def index
#jobs = Job.all
end
def new
#job = Job.new
end
def create
#job = Job.new(job_params)
if #job.save
redirect_to jobs_path, flash: { notice: "You've successfully created a job." }
else
redirect_to new_job_path, flash: { alert: #job.errors.messages }
end
end
def edit
#job = Job.find(params[:id])
end
def update
#job = Job.find(params[:id])
if #job.update
redirect_to jobs_path, notice: "You've updated a job."
else
redirect_to edit_job_path, alert: #job.errors.messages
end
end
def destroy
#job = Job.find(params[:id])
if #job.destroy
redirect_to jobs_path, notice: "You've deleted a job."
else
redirect_to jobs_path, alert: #job.errors.messages
end
end
private
def job_params
params.require(:job).permit(:poster, :category, :location, :status)
end
end
And the view:
<h1>Create job</h1>
<form class="form">
<%= form_for #job do |f| %>
<%= f.text_field :poster, placeholder: "Poster", onclick: "placeholder = ''", onblur: "placeholder = 'Poster'", autofocus: true, class: "form-group" %><br>
<%= f.text_field :category, placeholder: "Category", onclick: "placeholder = ''", onblur: "placeholder = 'Category'", class: "form-group" %><br>
<%= f.text_field :location, placeholder: "Location", onclick: "placeholder = ''", onblur: "placeholder = 'Location'", class: "form-group" %><br>
<%= f.select :status, ['New', 'Pending', 'Complete'],placeholder: "Status", onclick: "placeholder = ''", onblur: "placeholder = 'Status'", class: "form-group" %><br><br>
<%= f.submit "Submit", class: "btn btn-secondary" %>
<% end %>
</div>
And the log:
Started GET "/jobs/new?utf8=%E2%9C%93&authenticity_token=FStlZTVRMKg%2Bw3Zkw5%2FdpP1w5I%2Fl4vxlQPwAGKqRjIM704p6vXWXEe9z4GmdoB4FJirP6AzUJRkCPEcEwmVNjQ%3D%3D&job%5Bposter%5D=jill&job%5Bcategory%5D=jill&job%5Blocation%5D=jill&job%5Bstatus%5D=New&commit=Submit" for ::1 at 2017-04-16 15:16:08 -0400
Processing by JobsController#new as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"FStlZTVRMKg+w3Zkw5/dpP1w5I/l4vxlQPwAGKqRjIM704p6vXWXEe9z4GmdoB4FJirP6AzUJRkCPEcEwmVNjQ==", "job"=>{"poster"=>"jill", "category"=>"jill", "location"=>"jill", "status"=>"New"}, "commit"=>"Submit"}
Rendered jobs/new.html.erb within layouts/application (0.8ms)
Completed 200 OK in 13ms (Views: 12.1ms | ActiveRecord: 0.0ms)
This line is breaking your form
<form class="form">
You can't have nested forms in HTML. So <form> from your form_for definition is not interpreted as it should.
Also, there's a dangling </div>.

Nested Routes can not index all

I have nested routes as follows;
resources :boats, except: :destroy do
resources :pictures
end
So user can upload picture and everything works fine. But picture/index.html.erb. I can not see all the pictures. It returns nil. But I can see pictures in the database. Probably because I try to retrieve wrong parameter.
When I take out the if statement <% if #pictures.present? %> it throws and error;
NoMethodError in PicturesController#create
undefined method `each' for nil:NilClass
<% #pictures.each do |pic| %>
Here is #index view;
<div class="container">
<h1>Pictures#index!</h1>
<p>Find me in app/views/pictures/index.html.erb</p>
<% if #pictures.present? %> <!-- Returns nil-->
<% #pictures.each do |pic| %>
</br>
<%= pic.name %>
<%= image_tag pic.image_url(:thumb).to_s %>
<%= link_to "edit", edit_boat_picture_path(#boat, #picture) %> |
<td><%= link_to 'Destroy', [#boat, #picture], confirm: 'Are you sure?', method: :delete %></td> |
</br>
<% end %>
<% end %>
<%= link_to "edit", edit_boat_picture_path(#boat, #picture) %> |
</br>
</br>
<%= link_to "add", new_boat_picture_path(#boat, #picture) %>
</div>
So here, picture.present returns always nil, so I can not display any images.
Here is pictures controller;
class PicturesController < ApplicationController
before_action :logged_in_user
before_filter :load_parent
def index
#pictures = #boat.pictures.all
end
def new
#picture = #boat.pictures.new
end
def show
#picture = #boat.pictures.find(params[:id])
end
def create
#picture = #boat.pictures.new(picture_params)
if #picture.save
#flash[:success] = "Continue from here"
render 'index'
#redirect_to boat_path(#boat)
else
render 'new'
end
end
def edit
#picture = Picture.find(params[:id])
end
def update
#picture = #boat.pictures.find(params[:id])
if #picture.update_attributes(picture_params)
flash[:notice] = "Successfully updated picture."
render 'index'
else
render 'edit'
end
end
def destroy
#picture = #boat.pictures.find(params[:id])
#picture.destroy
flash[:notice] = "Successfully destroyed picture."
redirect_to boat_path(#boat)
end
private
def picture_params
params.require(:picture).permit(:name, :image)
end
def load_parent
#boat = Boat.find(params[:boat_id])
end
end
EDIT 1:
Log;
{"utf8"=>"✓", "authenticity_token"=>"i3FW1zbhoGW2vavipN9NJ2Fvi9R1Lk/CKDsAttuqHWb8rFNmJgXpjE2D25oAqJ3xp9BXAnd0kDmrdIxhn1Qrpw==", "picture"=>{"name"=>"", "image"=>#<ActionDispatch::Http::UploadedFile:0x007fb4a5f50f30 #tempfile=#<Tempfile:/var/folders/w0/703ccggs56l3hrc79h3rdylm0000gn/T/RackMultipart20150423-5028-1rbpgnj.jpg>, #original_filename="imgres-4.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"picture[image]\"; filename=\"imgres-4.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Done", "controller"=>"pictures", "action"=>"create", "boat_id"=>"114"}
EDIT 2:
if I add #pictures = #boat.pictures.all to create that is fine, but all pics have its own destroy button.And when I look at them all shows the same address, so clicking to destroy, destroys all of them;
All of the destroy ids are the same. I though index action lists all and destroy erases individually. This case is same for edit action too
EDIT 3:
#boats controller
class BoatsController < ApplicationController
before_action :logged_in_user, only: [:new, :show, :edit, :update]
def new
#boat = Boat.new
end
def create
#boat = current_user.boats.new(boat_params) if logged_in?
if #boat.save
#flash[:success] = "Continue from here"
render 'edit'
else
render 'new'
end
end
def show
#boat = Boat.find(params[:id])
end
def edit
#boat = Boat.find(params[:id])
end
def update
#boat = Boat.find(params[:id])
if #boat.update_attributes(boat_params)
flash[:success] = "The Boat Saved"
redirect_to root_path
else
render 'edit'
end
end
def update_years
# updates year and model based on brand selected
brand = Brand.find_by_name(params[:brand_name])
# map to name and id for use in our options_for_select
#years = brand.years.map{|a| [a.name, a.name]}.insert(0, "Select a Year") #use a.name here instead of a.id
#models = brand.models.map{|s| [s.name, s.name]}.insert(0, "Select a Model")#use s.name here instead of s.id
end
def update_models
# updates model based on year selected
year = Year.find_by_name(params[:year_name])
#models = year.models.map{|s| [s.name, s.name]}.insert(0, "Select a Model") #use s.name here instead of s.id
end
private
def boat_params
params.require(:boat).permit(:brand, :year, :model, :captained, :boat_type, :daily_price, :boat_length, :listing_tagline, :listing_description, :boat_category, :hull_material, :mast_material)
end
end
There is no #pictures in your create action.
You can try:
def create
#picture = #boat.pictures.new(picture_params)
if #picture.save
#flash[:success] = "Continue from here"
#pictures = #boat.pictures.all
render 'index'
#redirect_to boat_path(#boat)
else
render 'new'
end
end
For buttons:
<% #pictures.each do |pic| %>
</br>
<%= pic.name %>
<%= image_tag pic.image_url(:thumb).to_s %>
<%= link_to "edit", edit_boat_picture_path(#boat, pic) %> |
<td><%= link_to 'Destroy', boat_picture_path(#boat, pic), confirm: 'Are you sure?', method: :delete %></td> |
</br>
<% end %>

Ajax with Polymorphic Association (Destroy & Create)

I have a polymorphic association with dailyposts & comments in my rails app
Everything works fine in the database, but when I try to add Ajax to the Destroy Action (I used this tutorial http://railscasts.com/episodes/136-jquery-ajax-revised)
....it doesn't work unless I refresh the page. (but my alert works in destroy.js.erb)
I know my error is in destroy.js.erb
New to Rails...Please help :)
This is my code...
ROUTES
resources :dailyposts do
resources :comments
end
CONTROLLERS
##Dailyposts
class DailypostsController < ApplicationController
respond_to :html, :js
def show
#user = User.find_by_username(params[:username])
#dailypost = Dailypost.find_by_id(params[:id])
#commentable = #dailypost
#comments = #commentable.comments.arrange(:order => :created_at)
#comment = Comment.new
end
end
##Comments
class CommentsController < ApplicationController
before_filter :load_commentable
respond_to :html, :js
def create
#comment = #commentable.comments.create(params[:comment])
#comment.user = current_user
if #comment.save
respond_to do |format|
format.html { redirect_to #commentable }
format.js
end
else
redirect_to #commentable, notice: "Comment can't be blank."
end
end
def destroy
#comment = Comment.find(params[:id])
#commentable = #comment.commentable
if #comment.destroy
respond_to do |format|
format.html { redirect_to #commentable }
format.js
end
end
end
private
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
end
VIEWS
Dailypost show.html.erb
<div class="row-fluid">
<div class="span12">
<div>
<%= raw(dailypost_with_links(#dailypost)) %>
</div>
<%= render "comments/form" %>
<div id="comments">
<%= nested_comments #comments %>
</div>
</div>
</div>
_comment.html.erb
<section class="comments">
<div class ="user">
<%= link_to comment.user.username, comment.user %>
<%= comment.content %>
</div>
##Here I am passing remote: true for ajax
<% if current_user?(comment.user) %>
<%= link_to content_tag(:i, "", class: "icon-trash icons"), [#commentable, comment], method: :delete,
data: { confirm: "Are you sure?" },
title: "Delete", remote: true %> |
<% end %>
</section>
destroy.js.erb
##alert is working
alert('ajax works!');
$('#<%= dom_id(#comment) %>').remove();
LOGS
Started DELETE "/dailyposts/11/comments/133" for 127.0.0.1 at 2013-08-04 23:06:31 -0700
Processing by CommentsController#destroy as JS
Parameters: {"dailypost_id"=>"11", "id"=>"133"}
Dailypost Load (0.3ms) SELECT "dailyposts".* FROM "dailyposts" WHERE "dailyposts"."id" = ? ORDER BY dailyposts.created_at DESC LIMIT 1 [["id", "11"]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'sgFH2XeZWEXCcjxiAwgfXg' LIMIT 1
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT 1 [["id", "133"]]
Dailypost Load (0.1ms) SELECT "dailyposts".* FROM "dailyposts" WHERE "dailyposts"."id" = 11 ORDER BY dailyposts.created_at DESC LIMIT 1
(0.1ms) begin transaction
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE (comments.ancestry like '133/%' or comments.ancestry = '133')
SQL (0.4ms) DELETE FROM "comments" WHERE "comments"."id" = ? [["id", 133]]
(2.3ms) commit transaction
Rendered comments/destroy.js.erb (0.7ms)
Completed 200 OK in 25ms (Views: 10.3ms | ActiveRecord: 3.9ms)
Try this:
Dailypost show.html.erb
<div id="comments">
<%= render #comments %>
</div>
_comment.html.erb
<div id="<%= dom_id(comment) %>">
<%= comment.content %>
</div>
create.js.erb
$('<%= escape_javascript(render(:partial => #comment))%>').appendTo('#comments').hide().fadeIn();
destroy.js.erb
$('#<%= dom_id(#comment) %>').remove();
The redirect is breaking the response. Try changing it to redirect_to( :back ) unless request.xhr?
The problem is in destroy.js.erb , the second line does not work because there is no id like edit_comment_1 of the format edit_comment_(:id).
In your _comment.html.erb, add an appropriate div with id that is used in your .js.erb
<section class="comment">
<div id="edit_comment_<%= comment.id %>">
<div class ="user">
<%= link_to comment.user.username, comment.user %>
<%= comment.content %>
</div>
<% if current_user?(comment.user) %>
<%= link_to content_tag(:i, "", class: "icon-trash icons"), [#commentable, comment], method: :delete,
data: { confirm: "Are you sure?" },
title: "Delete", remote: true %> |
<% end %>
</div>
</section>

Resources