ActionController::UrlGenerationError in Comments#show - ruby-on-rails

I use polymorphic associations with comments. When I try to add 'edit' and also 'destroy' in show template, I get the error in the title (just edit for now). How do I add both links to show?
comments_controller.rb
class CommentsController < ApplicationController
....
before_action :signed_in_user, only: [:new, :edit]
before_filter :load_commentable
def index
#commentable = load_commentable
#comments = #commentable.comments
end
def show
end
def edit
#commentable = load_commentable
end
def new
#commentable = load_commentable
#comment = #commentable.comments.new
end
def create
#comment = #commentable.comments.new(comment_params)
#comment.user = current_user
if #comment.save
redirect_to #comment, notice: "Created."
else
render :new
end
end
def update
#comment = #commentable.comments.build(comment_params)
#comment.user = current_user
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to #comment, notice: 'It was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
private
def load_commentable
resource, id = request.path.split('/')[1, 2]
#commentable = resource.singularize.classify.constantize.find(id)
end
....
end
show.html.erb template
<%= link_to "Edit", [:edit, #commentable, :comment] %>
form
<%= form_for [#commentable, #comment] do |f| %>
....
full trace
log
Processing by CommentsController#show as HTML
Parameters: {"post_id"=>"1", "id"=>"2"}
Comment Load (0.3ms) SELECT "comments".* FROM "comments" WHERE
"comments"."id" = ? LIMIT 1 [["id", "2"]]
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" =
? LIMIT 1 [["id", "1"]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" =
? ORDER BY "users"."id" ASC LIMIT 1 [["id", 2]]
(0.2ms) SELECT COUNT(*) FROM "comments" WHERE "comments"."user_id" =
? [["user_id", 2]] CACHE (0.0ms) SELECT COUNT(*) FROM "comments"
WHERE "comments"."user_id" = ? [["user_id", 2]]
Rendered comments/show.html.erb within layouts/application (10.7ms)
Completed 500 Internal Server Error in 19ms
ActionView::Template::Error (No route matches {:action=>"edit",
:controller=>"comments", :post_id=>#, :id=>nil,
:format=>nil} missing required keys: [:id]):
25: <div class="thumbsdown"><%= link_to image_tag('othericons/thumbiconDown.PNG', height: '20', width: '20'),
"#" %>
26: <%= link_to image_tag('othericons/flagicon.PNG', height: '20', width: '18'), "#"
%>
27:
28: <%= link_to "Edit", [:edit, #commentable, :comment] %> 29:
30:
31: app/views/comments/show.html.erb:28:in
`_app_views_comments_show_html_erb___2937579164590753686_69833853514120'
Rendered /home/action/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb
(1.6ms) Rendered
/home/action/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
(1.2ms) Rendered
/home/action/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.erb
within rescues/layout (19.1ms)
routes:
resources :posts do
resources :comments
end

Change the Edit Link as below:
<%= link_to "Edit", edit_post_comment_path(#commentable, #comment) %>
You have setup Post and Comment as nested routes, so you need to pass objects of Post as well as Comment to the edit path.
EDIT
For Polymorphic association, you could use it as below:
<%= link_to "Edit", [:edit, #commentable, #comment] %>

Related

User signed in, but set to nil using Rails and Devise

devise (4.4.0)
Rails 5.1.4
I'm seeing this question asked a lot, but not finding the answer that works for me. I am showing that I am signing up and logging in, but current user set to nil. I'm thinking maybe it is the cookies, but I'm having a hard time parsing exactly how to fix that. One solution suggested adding
Rails.application.config.session_store :cookie_store, key: '_bejoy_session', domain: :all
to the config > session_store.rb which I did not have, but created and included. I'm just not sure what I'm missing here.
application controller:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
helper_method :current_user
helper_method :admin
def current_user
if session[:user_id]
#current_user ||= User.find(session[:user_id])
end
end
def authorize
if !current_user
flash[:alert] = "You aren't authorized to visit that page."
redirect_to '/'
end
end
def admin_authorize
if !current_user || current_user.admin == false
flash[:alert] = "Only administrators can visit that page."
redirect_to new_user_session_path
end
end
def admin
current_user && current_user.admin
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :admin, :email])
end
end
routes.rb
Rails.application.routes.draw do
root :to => 'contents#index'
resources :contents
resources :visitors
devise_for :users, controllers: {
sessions: 'users/sessions',
passwords: 'users/passwords',
registrations: 'users/registrations'
}
end
Terminal:
Started POST "/users/sign_in" for 127.0.0.1 at 2018-01-07 12:31:25 -0800
Processing by Users::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"6a0yiBCkmEN0W68xN/lVZH71YhT5i5tMEkFFYqnoIvMU0NJjH3LM3hPG+8yO3D1tXskh9pSA+PRFVKDmiKzN6A==", "user"=>{"email"=>"test#tester.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
User Load (1.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["email", "test#tester.com"], ["LIMIT", 1]]
(0.1ms) BEGIN
SQL (2.0ms) UPDATE "users" SET "current_sign_in_at" = $1, "last_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = $5 [["current_sign_in_at", "2018-01-07 20:31:26.091228"], ["last_sign_in_at", "2018-01-07 20:29:10.402839"], ["sign_in_count", 5], ["updated_at", "2018-01-07 20:31:26.092407"], ["id", 2]]
(0.4ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 152ms (ActiveRecord: 4.5ms)
Started GET "/" for 127.0.0.1 at 2018-01-07 12:31:26 -0800
Processing by ContentsController#index as HTML
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 2], ["LIMIT", 1]]
**current_user :nil
session id request :353a5e1d2bd295e8ac665e22e8f31314
user_signed_in? :false**
Rendering contents/index.html.erb within layouts/application
Content Load (0.2ms) SELECT "contents".* FROM "contents"
Rendered contents/index.html.erb within layouts/application (1.5ms)
Rendered partials/_author_photo_contact_block.html.erb (0.4ms)
Completed 200 OK in 53ms (Views: 49.1ms | ActiveRecord: 0.5ms)
contents controller:
class ContentsController < ApplicationController
before_action :authenticate_user!
# before_action :set_content, only: [:show, :edit, :update, :destroy]
def index
#contents = Content.all
logger.debug "current_user :#{current_user.inspect}"
logger.debug "session id request :#{request.session_options[:id]}"
logger.debug "user_signed_in? :#{user_signed_in?}"
end
def show
end
def new
#content = Content.new
end
def edit
end
def create
#content = Content.new(content_params)
respond_to do |format|
if #content.save
format.html { redirect_to #content, notice: 'Content was successfully created.' }
format.json { render :show, status: :created, location: #content }
else
format.html { render :new }
format.json { render json: #content.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #content.update(content_params)
format.html { redirect_to #content, notice: 'Content was successfully updated.' }
format.json { render :show, status: :ok, location: #content }
else
format.html { render :edit }
format.json { render json: #content.errors, status: :unprocessable_entity }
end
end
end
def destroy
#content.destroy
respond_to do |format|
format.html { redirect_to contents_url, notice: 'Content was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_content
#content = Content.find(params[:id])
end
def content_params
params.require(:content).permit(:main_image, :sidebar_image, :content, :sidebar)
end
end
Solution:
my current_user method in the application controller was overriding devise's own current_user method. I removed the current_user method I had in my application controller and it now shows:
current_user :#<User id: 2, email: "test#tester.com", username: "", admin: false, created_at: "2018-01-07 20:09:17", updated_at: "2018-01-07 21:33:51">
session id request :all
user_signed_in? :true
current user present? :true
found answer here: devise - can't display sign in or sign out in rails view

Posts Rating - Rails

I am implementing rating system in rails for posts.
On viewing a post one can rate the post by clicking radio button.
Below is the code. Consider only the post and rating don't consider tags, topics..
And there is no user in my concept one can rate whenever he needed and it should be added with existing rating of the post.
But, When I am doing this in log it shows the following:
Server log:
Started PATCH "/posts/34" for 127.0.0.1 at 2015-12-08 18:36:55 +0530
Processing by PostsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"l3aae99V424OyKVt5ULmqX2Mcs7DY2GYBskbLyhqqNENDn24ldCDAt4gNcgjESlFR6eaP0vcvrcoOerGE9lH5A==", "post"=>{"rating_ids"=>["5"]}, "commit"=>"Rate", "id"=>"34"}
Post Load (0.0ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", 34]]
CACHE (0.0ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", "34"]]
(0.0ms) begin transaction
SQL (4.0ms) INSERT INTO "ratings" ("star", "post_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["star", 5], ["post_id", 34], ["created_at", "2015-12-08 13:06:55.626133"], ["updated_at", "2015-12-08 13:06:55.626133"]]
(216.0ms) commit transaction
(0.0ms) begin transaction
Rating Load (1.0ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."id" = ? LIMIT 1 [["id", 5]]
Rating Load (0.0ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."post_id" = ? [["post_id", 34]]
SQL (2.0ms) UPDATE "ratings" SET "post_id" = NULL WHERE "ratings"."post_id" = ? AND "ratings"."id" IN (4, 25) [["post_id", 34]]
SQL (3.0ms) UPDATE "ratings" SET "post_id" = ?, "updated_at" = ? WHERE "ratings"."id" = ? [["post_id", 34], ["updated_at", "2015-12-08 13:06:55.878147"], ["id", 5]]
(170.0ms) commit transaction
Redirected to http://localhost:3000/topics/9
Completed 302 Found in 489ms (ActiveRecord: 397.0ms)
where it changes the post.id to NULL
SQL (2.0ms) UPDATE "ratings" SET "post_id" = NULL WHERE "ratings"."post_id" = ? AND "ratings"."id" IN (4, 25) [["post_id", 34]]
I don't know how this happens and how to overcome this So, Please help.
It changes the Rating database as below:
1st column: id, 2nd column: star, 3rd column: post_id
1,1,NULL
2,2,NULL
3,3,NULL
4,4,NULL
5,5,34
6,4,NULL
7,1,NULL
8,1,NULL
9,5,NULL
10,1,NULL
11,5,NULL
12,1,NULL
13,4,NULL
14,3,NULL
15,4,NULL
16,4,NULL
17,4,NULL
18,2,NULL
19,1,NULL
20,5,NULL
21,3,NULL
Post model:
class Post < ActiveRecord::Base
belongs_to :topic
has_many :comments
has_and_belongs_to_many :tags
has_many :ratings
end
Rating model:
class Rating < ActiveRecord::Base
belongs_to :post
end
Post show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #posts.name %> (
<%= #posts.topic.name %> )
</p>
<p>
<strong>Email:</strong>
<%= #posts.email %>
</p>
<p>
<strong>Message:</strong>
<%= #posts.message %>
</p>
<strong>Tags:</strong>
<% #posts.tags.each do |tag| %>
<div>
<%= tag.name %> <br>
</div>
<% end %>
<br>
<strong>Rating:</strong>
<%= #posts.ratings.group(:star).count %>
<%= form_for #posts do |f| %>
<% (1..5).each do |rating| %>
<%= radio_button_tag "post[rating_ids][]", rating %>
<%= rating %>
<% end %>
<%= f.submit('Rate') %>
<% end %>
<%= link_to 'Comments', post_comments_path(#posts) %>
<%= link_to 'Edit', edit_post_path(#posts) %> |
<%= link_to 'Back', topic_posts_url(#posts.topic) %>
Post controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
if params[:topic_id].to_i > 0
#topic = Topic.find(params[:topic_id])
#posts = #topic.posts.paginate(page: params[:page], per_page: 10)
else
#posts = Post.eager_load(:topic).paginate(page: params[:page], per_page: 10)
end
end
# GET /posts/1
# GET /posts/1.json
def show
#posts = Post.find(params[:id])
#tags = #posts.tags
#comment = Comment.new(:post => #posts)
end
# GET /posts/new
def new
#topic = Topic.find(params[:topic_id])
#posts = #topic.posts.new
end
# GET /posts/1/edit
def edit
#posts = Post.find(params[:id])
#tags = #posts.tags
end
# POST /posts
# POST /posts.json
def create
#topic = Topic.find(params[:topic_id])
#posts = #topic.posts.build(post_params)
respond_to do |format|
if #posts.save
format.html { redirect_to topic_url(#posts.topic_id), notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #posts }
else
format.html { render :new }
format.json { render json: #posts.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
#posts = Post.find(params[:id])
#tags = #posts.tags
respond_to do |format|
#posts.ratings.create(:star => params[:post][:rating_ids][0].to_i)
if #posts.update(post_params)
format.html { redirect_to topic_url(#posts.topic_id), notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #posts }
else
format.html { render :edit }
format.json { render json: #posts.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#posts.destroy
respond_to do |format|
format.html { redirect_to topic_url(#posts.topic_id), 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
#posts = 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(:name, :email, :message, :topic_id, {tag_ids:[]}, rating_ids:[])
end
end
I am new to rails and I need to implement this without using any gem..
Please help how it changes the post_id to NULL which I denoted in server log..
This is because after you created a Rating manually then goes #posts.update(rating_ids:[5]), which states that this post only should have rating with id 5, not 5 stars
Plus are you sure want your unauthenticated users to have access to post editing?
Since you save the rating before updating the post change your post_params to:
def post_params
params.require(:post).permit(:name, :email, :message, :topic_id, {tag_ids:[]})
end
As you are saving the rating from the params directly.
However you should consider changing your structure to use something like nested attributes which will automatically save/update ratings.

Ruby on Rails - Add Comments to Products

I am creating my first application in Rails, an e-commerce and would like to associate comments to the products, I created all the necessary structure, I have the user model, the products and the comments, I think I did everything right but when I go to render the form to insert the comment I get this error:
First argument in form can not contain nil or be empty
else
object = record.is_a?(Array) ? record.last : record
raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
object_name = options[:as] || model_name_from_record_or_class(object).param_key
apply_form_for_options!(record, object, options)
end
the view that renders the form is this
<%= form_for(#comment, html: {multipart: true}) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new comment..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<span class="picture">
<%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
</span>
<% end %>
<script type="text/javascript">
$('#comment_picture').bind('change', function() {
size_in_megabytes = this.files[0].size/1024/1024;
if (size_in_megabytes > 8) {
alert('Maximum file size is 8MB. Please choose a smaller file.');
}
});
Comments Controller
class CommentsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy, :show]
before_action :correct_user, only: :destroy
def show
#comment = Comment.find(params[:id])
end
def create
#comment = current_user.comment.build(comment_params)
if #comment.save
flash[:success] = "Comment created!"
redirect_to store_url
else
#feed_items = []
render 'static_pages/home'
end
end
def destroy
#comment.destroy
flash[:success] = "Comment deleted"
redirect_to request.referrer || store_url
end
private
def comment_params
params.require(:comment).permit(:content, :picture)
end
def correct_user
#comment = current_user.comments.find_by(id: params[:id])
redirect_to store_url if #comment.nil?
end
end
Show of Product Controller
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.paginate(page: params[:page])
end
# GET /products/1
# GET /products/1.json
def show
#product = Product.find(params[:id])
#comments = current_user.comments.build if logged_in?
#comments = #product.comments.paginate(page: params[:page])
#rating = Rating.where(product_id: #product.id, user_id: #current_user.id).first
unless #rating
#rating = Rating.create(product_id: #product.id, user_id: #current_user.id, score: 0)
end
end
User Controller
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def index
#users = User.where(activated: true).paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#comments = #user.comments.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to store_url
else
render 'new'
end
end
def update
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def edit
#user = User.find(params[:id])
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(store_url) unless current_user?(#user)
end
# Confirms an admin user.
def admin_user
redirect_to(store_url) unless current_user.admin?
end
end
I can post you also believe the models if necessary, thanks to all who help me.
Log file:
Started GET "/en/products/4" for 127.0.0.1 at 2015-07-12 20:30:01 +0200
Processing by ProductsController#show as HTML
Parameters: {"locale"=>"en", "id"=>"4"}
Product Load (0.2ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT 1 [["id", 4]]
CACHE (0.0ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT 1 [["id", "4"]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Rating Load (0.2ms) SELECT "ratings".* FROM "ratings" WHERE "ratings"."product_id" = ? AND "ratings"."user_id" = ? ORDER BY "ratings"."id" ASC LIMIT 1 [["product_id", 4], ["user_id", 1]]
(0.2ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."product_id" = ? [["product_id", 4]]
(0.2ms) SELECT COUNT(*) FROM "comments" WHERE "comments"."user_id" = ? [["user_id", 1]]
Rendered shared/_user_info.html.erb (3.0ms)
Rendered shared/_error_messages.html.erb (0.1ms)
(0.2ms) SELECT SUM("ratings"."score") FROM "ratings" WHERE "ratings"."product_id" = ? [["product_id", 4]]
CACHE (0.0ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."product_id" = ? [["product_id", 4]]
Rendered shared/_comment_form.html.erb (7.6ms)
CACHE (0.0ms) SELECT SUM("ratings"."score") FROM "ratings" WHERE "ratings"."product_id" = ? [["product_id", 4]]
CACHE (0.0ms) SELECT COUNT(*) FROM "ratings" WHERE "ratings"."product_id" = ? [["product_id", 4]]
Rendered products/show.html.erb within layouts/application (24.3ms)
Rendered layouts/_header.html.erb (5.9ms)
Rendered layouts/_footer.html.erb (1.1ms)
Completed 200 OK in 205ms (Views: 197.7ms | ActiveRecord: 1.1ms)
Started POST "/comments?locale=en" for 127.0.0.1 at 2015-07-12 20:30:11 +0200
Processing by StaticPagesController#home as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"1sIh3jNERiiitmbyHQaQpAomMIgjXKkBVA/RqsIYDhYkD73gFOeMKyYYtmjSr9mu0ngyKSephYmfJhvvlKMigg==", "comment"=>{"content"=>"Hello! "}, "commit"=>"Post", "locale"=>"comments"}
comments translation not available
Rendered static_pages/home.html.erb within layouts/application (70.2ms)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
Rendered layouts/_header.html.erb (4.4ms)
Rendered layouts/_footer.html.erb (0.6ms)
Completed 200 OK in 249ms (Views: 246.7ms | ActiveRecord: 0.2ms)

Nested Attribute Image Uploads Not Updating (Rails 4/ Carrierwave)

I'm using this example to create multiple image uploads using Carrierwave Rails 4 multiple image or file upload using carrierwave. For some reason if I edit the Post and try to upload a different image it doesn't update.
listings_controller.rb
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :except => [:show, :index]
def index
#listings = Listing.order('created_at DESC')
respond_to do |format|
format.html
format.json { render json: #listings }
end
end
def show
#image_attachments = #listing.image_attachments.all
end
def new
#listing = Listing.new
#listing.user = current_user
#image_attachment = #listing.image_attachments.build
end
def edit
end
def create
#listing = Listing.new(listing_params)
#listing.created_at = Time.now
#listing.user = current_user
respond_to do |format|
if #listing.save
params[:image_attachments]['image'].each do |a|
#image_attachment = #listing.image_attachments.create!(:image => a, :listing_id => #listing.id)
end
format.html { redirect_to #listing, notice: 'Post was successfully created.' }
else
format.html { render action: 'new' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #listing.update(listing_params)
flash[:notice] = 'Deal was successfully updated.'
format.html { redirect_to #listing }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
def destroy
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
#listing = Listing.friendly.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:condition, :listing_title, :nickname, :listing_size, :listing_price, :user_id, image_attachments_attributes: [:id, :listing_id, :image])
end
end
listing form
<%= form_for(#listing, :html => { :class => 'form', :multipart => true }) do |f| %>
<% if #listing.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#listing.errors.count, "error") %> prohibited this listing from being saved:</h2>
<ul>
<% #listing.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.fields_for :image_attachments do |p| %>
<div>
<%= p.label :image %>
<%= p.file_field :image, :multiple => true, name: "image_attachments[image][]", :class => 'upload' %>
</div>
<% end %>
<div class="actions">
<%= f.submit 'Submit', :class => 'submitButton' %>
</div>
<% end %>
listing.rb
has_many :image_attachments
accepts_nested_attributes_for :image_attachments
Any help? Thanks.
UPDATE
This is the log ouput when I try to update the image field. "about.png" is the new image I'm trying to upload.
Started PATCH "/listings/nike-air-max-90" for 127.0.0.1 at 2014-07-16 11:40:14 -0400
Processing by ListingsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LU1ADy5JqfuX9CMDtcG/dmGgu9nuvplDQrVixfICsS4=", "listing"=>{"listing_title"=>"Nike Air Max 90", "nickname"=>"", "listing_size"=>"9.5", "listing_price"=>"160", "image_attachments_attributes"=>{"0"=>{"id"=>"1"}}}, "image_attachments"=>{"image"=>[#<ActionDispatch::Http::UploadedFile:0x00000109506810 #tempfile=#<Tempfile:/var/folders/vk/x5f3g8n147z_j39_mzkbfq600000gp/T/RackMultipart20140716-1370-63vlgx>, #original_filename="about.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"image_attachments[image][]\"; filename=\"about.png\"\r\nContent-Type: image/png\r\n">]}, "commit"=>"Submit", "id"=>"nike-air-max-90"}
[1m[35mListing Load (0.2ms)[0m SELECT "listings".* FROM "listings" WHERE "listings"."slug" = 'nike-air-max-90' ORDER BY "listings"."id" ASC LIMIT 1
[1m[36mUser Load (0.2ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1[0m
[1m[35m (0.1ms)[0m begin transaction
[1m[36mImageAttachment Load (0.1ms)[0m [1mSELECT "image_attachments".* FROM "image_attachments" WHERE "image_attachments"."listing_id" = ? AND "image_attachments"."id" IN (1)[0m [["listing_id", 2]]
[1m[35m (0.1ms)[0m commit transaction
Redirected to http://localhost:3000/listings/nike-air-max-90
Completed 302 Found in 5ms (ActiveRecord: 0.6ms)
Option 1 (Replace all existing attachments with new uploaded ones
In your update action, you are NOT doing what you are doing in create action. Which is this:
params[:image_attachments]['image'].each do |a|
#image_attachment = #listing.image_attachments.create!(:image => a, :listing_id => #listing.id)
end
You can't expect Rails to do this for you magically because this is not a typical use of accepts_nested_attributes feature. In fact, in your current code, you are not using this feature at all.
If you want to make it work with your current code, you will have to delete all existing image_attachments and create the new ones in the update action, like this:
def update
respond_to do |format|
if #listing.update(listing_params)
if params[:image_attachments] && params[:image_attachments]['image']
# delete existing image_attachments
#listing.image_attachments.delete_all
# create new ones from incoming params
params[:image_attachments]['image'].each do |a|
#image_attachment = #listing.image_attachments.create!(:image => a, :listing_id => #listing.id)
end
end
flash[:notice] = 'Deal was successfully updated.'
format.html { redirect_to #listing }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
This will replace all existing images with new ones, if you upload new ones.
Option 2 (Edit them individually)
If you want to be able to update existing attachments, you will have to modify the edit form to allow updating attachment records individually. Or do it via proper use of accepts_nested_attributes feature. Cocoon is one great gem help you incorporate nested attributes in your forms easily.

Ruby Adding To Database

I am new in Ruby and I have to finish my school project. I have problem because we make one project in 14 people, everyone has his own part. I have to create new appointment but someone used this before and I cannot use this again (I want to add this simple from form). Please help me because I am stuck now, I don't want change someone's code. I render _form51.html.erb from new51.html.erb. Maybe I can use any simple redirect to create51?;> But I don't know how ;(
EDITED:
NOW SOLVED BUT why app create always empty appointment?
Routes.rb:
ZOZ::Application.routes.draw do
resources :refferals do
collection do
get 'new51'
end
member do
get 'show'
end
end
resources :appointments do
collection do
get 'search' #17
get 'search_result' #17
get 'to_confirm' #17
get 'search_not' #57
get 'search_result_not' #57
get 'add_or_edit_not' #57
get 'searchdate'
get 'searchd'
get 'move'
get 'new51'
post :create51
end
member do
put :confirm #17
put :update_not #57
get 'show51'
end
end
resources :clinics do
collection do
get 'index51'
end
member do
get 'show51s'
end
end
resources :doctors do
collection do
get 'index51a'
get 'index51'
get 'search54'
get 'search_result54'
get 'show_harmonogram'
end
member do
get 'show51s'
get 'show51ss'
end
end
resources :patients do
collection do
get 'select51'
get 'index51'
end
member do
get 'show51s'
get 'show51ss'
end
end
get "welcome/index2"
get "welcome/index"
get 'appointments/create'
get 'appointments/move' => 'appointments#move'
post 'appointments/move' => 'appointments#doctors_list'
get 'appointments/move/:id' => 'appointments#doctor_appointments', as: :doctor_appointments
get 'appointments/change_appointment/:id' => 'appointments#change_appointment', as: :change_appointment
get 'appointments/change_doctor_and_appointment/:id' => 'appointments#change_doctor_and_appointment', as: :change_doctor_and_appointment
get 'appointments/success' => 'appointments#success'
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root :to => 'welcome#index'
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
end
_form51.html.erb:
<%= form_for(#appointment) do |f| %>
<% if #appointment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#appointment.errors.count, "error") %> prohibited this appointment from being saved:</h2>
<ul>
<% #appointment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :data_godzina_wizyty %><br />
<%=
options = { start_year: 2.year.from_now.year,
end_year: 2013,
include_blank: true,
default: nil }
f.datetime_select :data_godzina_wizyty, options
%>
<!--<input type="text" data-behaviour='datepicker' :data_wizyty > -->
</div>
<div class="field">
<%= f.hidden_field :doctor_id, :value => Doctor.find(session[:current_doctor_id2]).id %>
</div>
<div class="field">
<%= f.hidden_field :patient_id, :value => Patient.find(session[:current_patient_id]).id %>
</div>
<div class="actions">
<%= submit_tag "Utworz wizyte" %>
</div>
<% end %>
New51.html.erb:
<div id="container">
<center>
<h1>Nowa wizyta:</h1>
<p>Sprawdz poprawnosc ponizszych danych a nastepnie uzupelnij formularz.</p>
<h3>Dane lekarza:</h3>
<p>
<strong>Imię lekarza:</strong>
<%= Doctor.find(session[:current_doctor_id2]).imie_lekarza %>
</p>
<p>
<strong>Nazwisko lekarza:</strong>
<%= Doctor.find(session[:current_doctor_id2]).nazwisko_lekarza %>
</p>
<p>
<strong>Specjalizacja lekarza:</strong>
<%= Doctor.find(session[:current_doctor_id2]).specjalizacja %>
</p>
<h3>Dane pacjenta:</h3>
<p>
<strong>Imie:</strong>
<%= Patient.find(session[:current_patient_id]).imie %>
</p>
<p>
<strong>Nazwisko:</strong>
<%= Patient.find(session[:current_patient_id]).nazwisko %>
</p>
<p>
<strong>Pesel:</strong>
<%= Patient.find(session[:current_patient_id]).pesel %>
</p>
<%= render 'form51' %>
<%= link_to 'Wybierz innego lekarza', index51_doctors_path %>
</br>
</center>
</div>
Appointments_Controller:
class AppointmentsController < ApplicationController
before_filter :load_appointment, only: [:show, :update, :edit, :destroy]
before_filter :load_wizard, only: [:new, :edit, :create]
def searchd
end
def move
end
def doctors_list
#doctors = Doctor.where("imie_lekarza like ? or nazwisko_lekarza LIKE ? or specjalizacja LIKE ?", "%#{params[:search]}%", "%#{params[:search]}%", "%#{params[:search]}%")
end
def doctor_appointments
#doctor = Doctor.find(params[:id])
#appointments = #doctor.appointments
end
def change_appointment
#appointment = Appointment.find(params[:id])
end
def change_doctor_and_appointment
#doctors = Doctor.all
#appointment = Appointment.find(params[:id])
end
def success
#notice = flash[:notice]
end
def searchdate
d = params[:date]
data = Date.new(d["(1i)"].to_i, d["(2i)"].to_i, d["(3i)"].to_i)
#appointments = Appointment.scoped
#appointments = #appointments.where(:data_godzina_wizyty => data.beginning_of_day..data.end_of_day)
end
def search_not
end
def search_result_not
#pacjent
#patients = Patient.scoped
#patients = #patients.where(pesel: params[:pesel])
d = params[:date]
if d["(1i)"] != "" and d["(2i)"]. != "" and d["(3i)"] != ""
data = Date.new(d["(1i)"].to_i, d["(2i)"].to_i, d["(3i)"].to_i)
#appointments = #patients.first.appointments.where(:data_godzina_wizyty => data.beginning_of_day..data.end_of_day)
else
#appointments = #patients.first.appointments
end
end
def add_or_edit_not
session['last_search_not'] = request.env["HTTP_REFERER"]
#appointment = Appointment.find(params[:id])
#patient = Patient.find(#appointment.patient_id)
if #appointment.doctor_id != nil
#doctor = Doctor.find(#appointment.doctor_id)
end
if #appointment.refferal_id != nil
#refferal = Refferal.find(#appointment.refferal_id)
end
end
def update_not
#appointment = Appointment.find(params[:id])
#appointment.notatka = params[:notatka]
if #appointment.save
redirect_to session[:last_search_not], notice: 'Notatka zostala zapisana.'
else
redirect_to :back, notice: 'Niestety wystapil blad. Prosze sprubowac pozniej'
end
end
def search
end
def new51
#appointment = Appointment.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #appointment }
end
end
def create51
#appointment = Appointment.new(params[:patient])
respond_to do |format|
if #appointment.save
format.html { redirect_to #appointment, notice: 'Szczegoy wizyty pomyslnie zmodyfikowane!' }
format.json { render json: #appointment, status: :created, location: #appointment }
else
format.html { render action: "new" }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
def search_result
d = params[:date]
data = Date.new(d["(1i)"].to_i, d["(2i)"].to_i, d["(3i)"].to_i)
#szukanie pacjenta
#patients = Patient.scoped
#patients = #patients.where(pesel: params[:pesel])
if params[:imie] != ""
#patients = #patients.where(imie: params[:imie])
end
if params[:nazwisko] != ""
#patients = #patients.where(nazwisko: params[:nazwisko])
end
#szukanie doctora
opcja = 0
#doctors = Doctor.scoped
if params[:imie_lekarza] != ""
#doctors = #doctors.where(imie_lekarza: params[:imie_lekarza])
opcja = 1
end
if params[:nazwisko_lekarza] != ""
#doctors = #doctors.where(nazwisko_lekarza: params[:nazwisko_lekarza])
opcja = 1
end
#zlaczenie
#patient_appo = #patients.first.appointments.where(:data_godzina_wizyty => data.beginning_of_day..data.end_of_day, potwierdzona: false)
if opcja == 1
#doctors_appo = #doctors.first.appointments.where(:data_godzina_wizyty => data.beginning_of_day..data.end_of_day, potwierdzona: false)
#appointments = #patient_appo & #doctors_appo
else
#appointments = #patient_appo
end
end
def to_confirm
session['last_search'] = request.env["HTTP_REFERER"]
#appointment = Appointment.find(params[:id])
#patient = Patient.find(#appointment.patient_id)
if #appointment.doctor_id != nil
#doctor = Doctor.find(#appointment.doctor_id)
end
if #appointment.refferal_id != nil
#refferal = Refferal.find(#appointment.refferal_id)
end
end
def confirm
#appointment = Appointment.find(params[:id])
#appointment.potwierdzona = true
if #appointment.save
#redirect_to :back, notice: 'Rejestracja zostala pomyslnie potwierdzona.'
redirect_to session[:last_search], notice: 'Rejestracja zostala pomyslnie potwierdzona.'
else
redirect_to :back, notice: 'Niestety wystapil blad. Prosze sprubowac pozniej'
end
end
def index
#appointments = Appointment.all
end
def show
end
def new
#appointment = #wizard.object
#clinics = Clinic.all
#doctors = Doctor.all
end
public
def findDoctorViaClinic( clinic )
return( (Clinic.find( clinic )).doctors.uniq )
end
helper_method :findDoctorViaClinic
def findScheduleViaDoctor(d)
s = Schedule.includes(:doctors_workplace).where(doctors_workplace_id: (DoctorsWorkplace.includes(:doctor).where(doctor_id: d)) ).where(taken: 0)
return s
end
helper_method :findScheduleViaDoctor
def edit
end
def create
#appointment = #wizard.object
if #wizard.save
s = ( Schedule.find( #appointment.schedule.id ) )
s.taken = true
s.save
redirect_to #appointment, notice: "Appointment saved!"
else
render :new
end
end
def update
# if #wizard.save
# redirect_to #appointment, notice: 'Appointment was successfully updated.'
# else
# render action: 'edit'
# end
#appointment = Appointment.find(params[:id])
#old_appointment = #appointment.dup
respond_to do |format|
if #appointment.update_attributes(params[:appointment])
DefaultMailer.move_appointment(#appointment, #old_appointment).deliver
format.html { redirect_to appointments_success_path, notice: 'Pomyslnie zmieniono termin.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
def destroy
#appointment.destroy
redirect_to appointments_url
end
private
def load_appointment
#appointment = Appointment.find(params[:id])
end
def load_wizard
#wizard = ModelWizard.new(#appointment || Appointment, session, params)
if self.action_name.in? %w[new edit]
#wizard.start
elsif self.action_name.in? %w[create update]
#wizard.process
end
end
end
Logs:
Started POST "/appointments/create51" for 127.0.0.1 at 2014-06-22 08:22:53 +0200
Processing by AppointmentsController#create51 as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"kMxnErrH13opSkUPbg9hRM0Sy5JVwDCAbGRDNP5BSfc=", "appointment"=>{"data_godzina_wizyty(1i)"=>"2015", "data_godzina_wizyty(2i)"=>"1", "data_godzina_wizyty(3i)"=>"17", "data_godzina_wizyty(4i)"=>"16", "data_godzina_wizyty(5i)"=>"15", "doctor_id"=>"1", "patient_id"=>"1"}, "commit"=>"Utworz wizyte"}
[1m[35m (0.0ms)[0m begin transaction
[1m[36mSQL (2.0ms)[0m [1mINSERT INTO "appointments" ("clinic_id", "created_at", "data_godzina_wizyty", "data_wizyty", "doctor_id", "godzina_wizyty", "notatka", "objawy_choroby", "patient_id", "potwierdzona", "refferal_id", "schedule_id", "updated_at", "wymaga_Potwierdzenia") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)[0m [["clinic_id", nil], ["created_at", Sun, 22 Jun 2014 06:22:53 UTC +00:00], ["data_godzina_wizyty", nil], ["data_wizyty", nil], ["doctor_id", nil], ["godzina_wizyty", nil], ["notatka", nil], ["objawy_choroby", nil], ["patient_id", nil], ["potwierdzona", nil], ["refferal_id", nil], ["schedule_id", nil], ["updated_at", Sun, 22 Jun 2014 06:22:53 UTC +00:00], ["wymaga_Potwierdzenia", nil]]
[1m[35m (13.0ms)[0m commit transaction
Redirected to http://localhost:3000/appointments/30
Completed 302 Found in 23.0ms (ActiveRecord: 15.0ms)
Started GET "/appointments/new51" for 127.0.0.1 at 2014-06-22 08:22:42 +0200
Processing by AppointmentsController#new51 as HTML
[1m[35mDoctor Load (1.0ms)[0m SELECT "doctors".* FROM "doctors" WHERE "doctors"."id" = ? LIMIT 1 [["id", 1]]
[1m[36mCACHE (0.0ms)[0m [1mSELECT "doctors".* FROM "doctors" WHERE "doctors"."id" = ? LIMIT 1[0m [["id", 1]]
[1m[35mCACHE (0.0ms)[0m SELECT "doctors".* FROM "doctors" WHERE "doctors"."id" = ? LIMIT 1 [["id", 1]]
[1m[36mPatient Load (0.0ms)[0m [1mSELECT "patients".* FROM "patients" WHERE "patients"."id" = ? LIMIT 1[0m [["id", 1]]
[1m[35mCACHE (0.0ms)[0m SELECT "patients".* FROM "patients" WHERE "patients"."id" = ? LIMIT 1 [["id", 1]]
[1m[36mCACHE (0.0ms)[0m [1mSELECT "patients".* FROM "patients" WHERE "patients"."id" = ? LIMIT 1[0m [["id", 1]]
[1m[35mCACHE (0.0ms)[0m SELECT "doctors".* FROM "doctors" WHERE "doctors"."id" = ? LIMIT 1 [["id", 1]]
[1m[36mCACHE (0.0ms)[0m [1mSELECT "patients".* FROM "patients" WHERE "patients"."id" = ? LIMIT 1[0m [["id", 1]]
Rendered appointments/_form51.html.erb (13.0ms)
Rendered appointments/new51.html.erb within layouts/application (22.0ms)
Rendered welcome/_form.html.erb (1.0ms)
Completed 200 OK in 103.0ms (Views: 100.9ms | ActiveRecord: 1.0ms)
Started GET "/appointments/30" for 127.0.0.1 at 2014-06-22 08:22:53 +0200
Processing by AppointmentsController#show as HTML
Parameters: {"id"=>"30"}
[1m[36mAppointment Load (0.0ms)[0m [1mSELECT "appointments".* FROM "appointments" WHERE "appointments"."id" = ? LIMIT 1[0m [["id", "30"]]
Rendered appointments/show.html.erb within layouts/application (2.0ms)
Rendered welcome/_form.html.erb (1.0ms)
Completed 200 OK in 80.0ms (Views: 77.0ms | ActiveRecord: 0.0ms)
Routes
Wow your routes are really WET
You really need to read up on resourceful routing - every route you have in your routes file really needs to be associated to a particular controller (apart from root to and other wildcards)
Whoever wrote your routes file has laden it with massive numbers of specific actions. Frankly, it's a mess and I would highly recommend you go through & remove any custom actions you've got in there.
Resourceful routing is described in the Rails docs as thus:
Bottom line is you shouldn't be creating routes for specific records; you need to create a system to handle the different processes your application will have
--
Form
If you're not seeing any object created in your db, there could be a number of problems. The biggest, though, is your use of an #instance variable in your partial.
To the best of my knowledge, partials don't carry #instance variables through to their render process. You have to pass local variables:
#new.html.erb
<%= render "form51", locals: { appointment: #appointment } %>
#_form51.html.erb
<%= form_for appointment do |f| %>
...
<% end %>
--
Being honest, there's so much to fix with this, it will be best if you ask for help in the comments here - so I can pinpoint exactly what needs to be fixed
You problem comes from the url you use on your form.
You should try like this on your _form51.html.erb:
form_for #appointment, :url => url_for(:action => "create51") do |f|
If you do rake routes | grep 'create51' you'll have the rails path. Then you can also do like this:
form_for #appointment, :url => create51_path do |f|
(here I suppose the command gave you create51 as path).

Resources