cant upload images rails and error occur - ruby

I want to upload an image to my localhost using gem 'carrierwave', i have painting and galleries controller like below code
painting controller
class PaintingsController < ApplicationController
def index
#paintings=Painting.all
end
def new
#painting=Painting.new
end
def show
#painting=Painting.find(params[:id])
end
def create
#byebug
#painting=Painting.new(painting_params)
if #painting.save
flash[:success]="Created image in album"
redirect_to gallery_path(#painting)
else
flash[:error]="Fail!"
render 'new'
end
end
private
def painting_params
params.require(:painting).permit(:name,:gallery_id)
end
end
Gallery controller
class GalleriesController < ApplicationController
def index
#galleries=Gallery.all
end
def new
#gallery=Gallery.new
end
def show
#gallery=Gallery.find(params[:id])
end
def create
#gallery=Gallery.create!(gallery_params)
redirect_to galleries_path
end
private
def gallery_params
params.require(:gallery).permit(:name)
end
end
ok then 2 model files :
gallery.rb
class Gallery < ApplicationRecord
has_many :paintings
end
painting.rb
class Painting < ApplicationRecord
def access_params
params.require(:painting).permit(:gallery_id, :name, :image)
end
belongs_to :gallery, optional: true
mount_uploader :image, ImageUploader
end
It seems everying goes well but then i stuck at the step showing image on show.html.erb in gallery.
show.html.erb
<div id="paintings">
<% #gallery.paintings.each do |painting| %>
<div class="painting">
<%= image_tag painting.image_url.to_s %>
<div class="name"><%= painting.name %></div>
<div class="actions">
<%= link_to "edit", edit_painting_path(painting) %> |
<%= link_to "remove", painting, :confirm => 'Are you sure?', :method => :delete %>
</div>
</div>
<% end %>
<div class="clear"></div>
</div>
the image isn't showed up althought flash in gallery 's controller reported that i created the image,i inspected the website then i tried print painting s'attributes on show.html.erb
<%= #gallery.name %>
<%= #gallery.paintings.name %>
<%= #gallery.paintings.gallery_id%>
<%= #gallery.paintings.image%>
Only gallery's name and painting's name are printed out. other two methods has an error occur.
undefined method `gallery_id' for #<ActiveRecord::Associations::CollectionProxy []>
I don't know why gallery can only access to painting's name but not others two.I searched for this error but i dont think those situation apply to mine . What is the problem guys?

Your "paintings" is a collection, not a single image, so you need to either iterate on each of them or select the first one:
<%= #gallery.paintings.first.name %>
<%= #gallery.paintings.first.gallery_id %>
<%= #gallery.paintings.first.image %>

I found my error ! in user controller add :image to method painting_params
def painting_params
params.require(:painting).permit(:name,:gallery_id,:image)
end

Related

Nested formed by cocoon cannot be saved

Problem
I'm coding user's profile page on Rails.
I added a gem "language-select" for users to choose a language which they're learning. And users might learn several languages, so I added gem "cocoon" as well.
The first language which users choose is successfully saved, but others which were chosen by cocoon cannot be saved. I would like them to be saved and being showed on their profile page.
How I reached this problem
I added cocoon by refering this page and code.README in github
However, "Save" button didn't react anything, so I made the form_for's method "post".
<%= form_for #user, method: :post do |f| %>
<div id='languages'>
<%= f.fields_for :languages do |language| %>
<%= render 'language_fields', :f => language %>
<% end %>
<div class='links'>
<%= link_to_add_association 'add language', f, :languages %>
</div>
</div>
<% end %>
Then "Save" button worked, but an error occured.
ActionController::InvalidAuthenticityToken in UsersController#update
ActionController::InvalidAuthenticityToken
Extracted source (around line #211):
def handle_unverified_request
raise ActionController::InvalidAuthenticityToken
end
end
end
Therefore, I added "protect_from_forgery with: :null_session" to application_controller.rb. Then the error disappeared, but the problem which I mentioned above occered. The first language which users choose is saved, but other ones which were chosen by cocoon cannot be saved.
(users#show.html.erb)
<h2><%= #user.language %></h2>
(users#edit.html.erb)
<%= form_tag("/users/#{#user.id}/update", {multipart: true}) do %>
<table>
<p>Languages</p>
<%= select_tag(:language,options_for_select(languages)) %>
<%= render 'users/form' %>
<input type="submit" value="Submit">
</table>
<% end %>
(users#_form.html.erb)
Partial of cocoon.
<%= form_for #user, method: :post do |f| %>
<div id='languages'>
<%= f.fields_for :languages do |language| %>
<%= render 'language_fields', :f => language %>
<% end %>
<div class='links'>
<%= link_to_add_association 'add language', f, :languages %>
</div>
</div>
<% end %>
(users#_language.html.erb)
Partial of cocoon.
<div class='nested-fields'>
<div class="field">
<%= select_tag(:language,options_for_select(languages)) %>
</div>
<%= link_to_remove_association "remove language", f %>
</div>
(users_controller.rb)
Even though I settled "redirect_to("/users/#{#user.id}")" here, it redirects to "/posts/index" after press "Save" button. And the sentence "You're already logged in" which I settled at "forbid_login_user" in "application_controller.rb" is shown too.
before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
before_action :ensure_correct_user, {only: [:edit, :update]}
def edit
#user = User.find_by(id: params[:id])
end
def user_params
params.require(:user).permit(:name, :description, languages_attributes: [:id, :description, :done, :_destroy])
end
def update
#user = User.find_by(id: params[:id])
#user.language = params[:language]
if params[:image]
#user.image_name = "#{#user.id}.jpg"
image = params[:image]
File.binwrite("public/user_images/#{#user.image_name}", image.read)
end
if params[:cover_image]
#user.cover_image_name = "#{#user.id}_cover.jpg"
cover_image = params[:cover_image]
File.binwrite("public/user_cover_images/#{#user.cover_image_name}", cover_image.read)
end
if #user.save
flash[:notice] = "Edited user's information"
redirect_to("/users/#{#user.id}")
else
render("users/edit")
end
end
(application_controller.rb)
class ApplicationController < ActionController::Base
protect_from_forgery with: :null_session
before_action :set_current_user
def set_current_user
#current_user = User.find_by(id: session[:user_id])
end
def authenticate_user
if #current_user == nil
flash[:notice] = "You need to log in"
redirect_to("/login")
end
end
def forbid_login_user
if #current_user
flash[:notice] = "You're already logged in"
redirect_to("/posts/index")
end
end
end
I will add more code if it needs to be refered. Thank you very much.
Version
ruby 2.6.4p104 / RubyGems 3.0.3 / Rails 5.2.3
Postscript
When I choose only one language, it can be saved.
When I choose like several languages like below, the problem which I mentoined above happens. Nothing is saved.
But after putting "skip_before_action :verify_authenticity_token" in application_controller.rb, only "English"(the last one) is saved (checked by rails console).
"Japanese" (chose by original form)
"English" (added and chose by cocoon)
Anyway, only 1 language can be saved so far.

Ruby on Rails error when using same form on multiple pages

I have a contact form setup and working on my 'Contact' page. However, when I copy that form to another page I get this error: 'First argument in form cannot contain nil or be empty'.
Here is my contactcontroller:
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
if #contact.valid?
ContactMailer.contact_email(#contact).deliver_now
redirect_to new_contact_path, notice: "Your email has been sent. Thank you."
else
render :new
end
end
end
Here is the other page controller:
class GolfcoursesController < ApplicationController
protect_from_forgery
def index
#golf_courses = GolfCourse.all
end
def show
#golf_courses = GolfCourse.all
#golfcourse = GolfCourse.find_by(slug: params[:slug])
#holes = #golfcourse.golf_holes
end
def events
end
def membership
end
def practice_facilities
end
def contact
end
def golf
#golf_courses = GolfCourse.all
end
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
if #contact.valid?
ContactMailer.contact_email(#contact).deliver_now
redirect_to new_contact_path, notice: "Your email has been sent. Thank you."
else
render :new
end
end
end
And here is the form:
<div class="container">
<h4>Let us know if you have any questions.</h4>
<%= form_for #contact, :html => {:role => 'form'} do |f| %>
<div class="form-group">
<%= f.label :name, 'Enter your name:' %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email, 'Email:' %>
<%= f.email_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :message, 'Message:' %>
<%= f.text_area :message, class: 'form-control', :rows => 3 %>
</div>
<div class="form-group">
<%= f.submit 'Submit', class: 'btn btn-default' %>
</div>
<% end %>
</div>
Thanks in advance for any help!
'First argument in form cannot contain nil or be empty'
You should also initialize the #contact in your other controller.
If you would like to share forms, I'd suggest the use of partials and passing in locals. This makes your code also somewhat DRY.
For reference also see the rails guides:
http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

Issue with paperclip, upload image

I have some problem with paperclip gem. When I try add record in my app i got error : http://postimg.org/image/xy0stdctd/
When i add record without image upload, everything works great.
controller
def create
#user = User.new
end
def made
#user = User.new(user_params)
if #user.save
redirect_to(action:'index' )
else
render ('index')
end
end
def user_params
params.require(:user).permit(:avatar, :name)
end
view
<%= form_for :user, url: {action: 'made'}, :html => { :multipart => true } do |form| %>
<%= form.text_field :name %>
<br>
<%= form.file_field :avatar %>
<br>
<%= form.submit "dodaj" %>
<% end %>
in terminal I have
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (8.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
Rendered C:/RailsInstaller/Ruby2.1.0/lib/ruby/gems/2.1.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/
layout (130.0ms)
Cannot render console with content type multipart/form-dataAllowed content types: [#, #, #]

Can not create user with Rails app on heroku, but works perfect on localhost

So I am working through the Michael Hartl tut and this app works perfectly on the localhost but the moment I deploy to heroku it wont create a user when i submit the information. In fact it just sits there as if I just clicked on an empty screen, no error message nor a rediret. I looked at the heroku logs and there are no exceptions that I can see being logged. I tried updating the controller behavior but i get the same result. This is frustrating.
my form looks like this:
<div class="main-form">
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages'%>
<%= f.label :name %>
<%= f.text_field :name, class: "active" %><br/>
<%= f.label :email %>
<%= f.text_field :email %><br/>
<%= f.label :password %>
<%= f.password_field :password %><br/>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %><br/>
</div>
<div class="actions">
<%= f.submit "create my account", class: "btn btn-lg btn-default" %>
</div>
<% end %>
my controller looks like:
class UsersController < ApplicationController
def new
end
def show
#user = User.find(params[:id])
#title = #user.name
end
def create
#title = "welcome"
#user = User.new(user_params)
if #user.password_confirmation.empty? == false
#user.save
redirect_to user_path(#user)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
i have also tried setting up my create method like:
def create
#user = User.new(user_params)
if #user.save
redirect_to #user
else
render 'new'
end
end
neither of these methods worked? Any advice would be welcome.
If you inspect the page it looks like your submit button is outside of the form definition:

undefined method `bookings_path'

I have a form to fill in booking details, but I'm getting the following error:
NoMethodError in Bookings#new
undefined method `bookings_path'
This happened after change the routes.rb file, to nest the booking resources in the user resource.
My form file code is the following:
<% provide(:title, 'Book Now!') %>
<section id="book-now">
<%= form_for(#booking) do |f| %>
<header>
<h1>Edit booking</h1>
</header>
<%= f.text_field :name, placeholder: "Name" %>
<%= f.text_field :check_in, placeholder: "Check-in" %>
<%= f.text_field :check_out, placeholder: "Check-out" %>
<%= f.submit "Save" %>
<% end %>
</section>
My booking controller code is:
class BookingsController < ApplicationController
def new
#booking = Booking.new
end
def create
#booking = Booking.new(params_bookings)
#booking.user_id ||= current_user.id
if #booking.save
redirect_to user_path(#booking.user_id)
else
# render 'new'
end
end
end
private
def params_bookings
params.require(:booking).permit(:check_in, :check_out, :name, :user_id)
end
end
and my routes.rb file looks like this:
Hightide::Application.routes.draw do
resources :users do
resources :bookings
end
match '/users/:user_id/bookings/new', to: 'bookings#new', via: [:post, :get]
you have this error because your bookings routes are nested to the users, so when you write this
form_for #booking
you essentially call
form_for bookings_path, ...
coz rails gets the type of the object you send to form_for and tries to get vanilla path for it.
to solve the problem you need either create the vanilla bookings resources in your routes, or specify both a user and a booking reference for the form_for call, like so
form_for [current_user, #booking]

Resources