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.
Related
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
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: [#, #, #]
Please help me to solve the below error.
Error:
ActionController::ParameterMissing in CustmersController#create
param is missing or the value is empty: users
When i am submitting the data,this error is coming.
My code is as follows
views/custmers/new.html.erb
<h1>Enter your data here</h1>
<center>
<%= form_for #users,:url => {:action => 'create'} do |f| %>
<% if #users.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#users.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #users.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<label for="name">Name:</label>
<%= f.text_field :name,placeholder:"Enter your name",:class => "input-field" %>
</p>
<p>
<label for="email">Email:</label>
<%= f.email_field :email,placeholder:"Enter your email",:class => "input-field" %>
</p>
<p>
<label for="phone">Phone no:</label>
<%= f.telephone_field :phoneno,placeholder:"Enter your phone number",:class => "input-field" %>
</p>
<p>
<%= f.submit "Submit" %>
</p>
<% end %>
<%= link_to "BACK",custmers_index_path %>
</center>
controller/custmers_controller.rb
class CustmersController < ApplicationController
def index
end
def new
#users=Custmer.new
end
def show
end
def create
#users=Custmer.new(user_params)
if #users.save
flash[:notice]="You have signed up successpully"
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:alert]="You have not signed up successfully"
flash[:color]="invalid"
render :new
end
end
private
def user_params
params.require(:users).permit(:name,:email,:phoneno)
end
end
model/custmer.rb
class Custmer < ActiveRecord::Base
EMAIL_REGEX = /\A[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
validates :name,presence:true,length: { minimum: 5 }
validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
validates :phoneno, presence: true,length: {minimum: 10}
end
I am using rails version-4.2.0 and ruby version-1.9.3.Please help me to resolve this error.
If you look at the stack trace accompanying your error, you could tell definitely where the problem is -- look for the first line in the stack trace that refers to your code (and not library code).
But a fair guess is the require(:users) line in your controller. It looks like you either copy/pasted this code from another controller, or changed the name of your controller after generating it as part of your scaffold.
It should be requires(:custmer) instead, as that is the class of the thing you're submitting.
As a general approach, you should follow the standard Rails practices for naming things, throughout. If you really want to use the misspelled, Custmer class, have at it, but use #custmr inside your controller and views to refer to an instance, not #users.
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:
I'm trying to create a new record in rails using the form_for helper method. I think the params hash is blank because I keep getting blank errors when I submit the form.
This is my form:
<% provide(:title, "Add Department") %>
<h1>Add Department</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#department) do |f| %>
<%= render 'shared/department_error_messages' %>
<%= f.label :Full_Department_Title %>
<%= f.text_field :full_name %>
<%= f.label :Department_Abbreviation %>
<%= f.text_field :abbreviation %>
<%= f.submit "Add department", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
This is my departments controller
class DepartmentsController < ApplicationController
def show
#department = Department.find(params[:id])
end
def new
#department = Department.new
end
def create
#department = Department.new(params[department_params]) # Not the final implementation!
if #department.save
redirect_to root_path
else
render 'new'
end
end
private
def department_params
# This says that params[:department] is required, but inside that, only params[:department][:full_name] and
# params[:department][:abbreviation] are permitted. Unpermitted params will be stripped out
params.require(:department).permit(:full_name, :abbreviation)
end
end
This is the Model:
class Department < ActiveRecord::Base
validates :full_name, presence: true, length: { minimum: 6 }
end
When I submit, errors are rendered saying the full_name can't be blank (and the fields are now empty). The debug info is:
--- !ruby/hash:ActionController::Parameters utf8: ✓
authenticity_token: EjfYjWAzaw7YqVZAkCPZwiEMFfb2YLIRrHbH1CpZOwA=
department: !ruby/hash:ActionController::Parameters
full_name: Sports Department
abbreviation: SD
commit: Add department
action: create
controller: departments
I've also checked the development log. The transaction starts and is then rolled back. I can save a record in the console so I'm guessing its something to do with the params hash, but can't figure it out. Please help
This line:
#department = Department.new(params[department_params])
Should be:
#department = Department.new(department_params)
And, as a minor issue (but not causing this problem), your label tags should look like:
f.label :full_name, "Full Department Title"
This way they are correctly associated with the input.