i have the following situation:
I have a controller for admins , that i use to manage the users (model generated by Devise).
So, i use the actions of another controller to manage the resources "users".
Here my files:
admins_controller.rb
before_action :set_user, only: [:show, :edit, :update, :destroy]
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to admins_index_path, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:id)
end
edit.html.erb
<h1>Edit user</h1>
<%= form_for #user, :as => :patch, :url => admins_update_path(id: #user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this line_item from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :id %><br>
<%= f.text_field :id %>
</div>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :admin %><br>
<%= f.text_field :admin %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
The problem is that when i submit the edit , rails gives me an error:
Can you help me? i really don t knok how to fix
thank you
EDIT:
Change your view to drop the :as option, that will fix the params requirement error:
= form_for #user, :url => admins_update_path(id: #user) do |f|
The :as tells form_for to use a different key name than the default class-name based one that you're using in your params.require call.
You should also remove your f.text_field :id - you don't want someone editing that.
Then your permit(...) block will need to include anything else in that form that you want to allow mass-assignment for, most likely you'll want: permit(:email, :admin)
Related
I need to extract a parameter from my url and insert it into my database for a referral system.
Let's say this user, which is id = 1 has shared his link with another user, the url would be:
https://www.example.com/signup?referredBy=1
When the new user creates his account, I want the field referredBy to be assigned with the value from the referredBy parameter, which should be an Integer.
I've tried to do
#user.referredBy = [:referredBy]
But it didn't worked out.
Any help is appreciated.
Thank you so much.
EDIT
My index.html.erb is:
<% if current_user %>
Logged in as <%= current_user.nomeUsuario %>
<%= link_to "Log out", logout_path %>
<% end %>
<p id=”notice”><%= notice %></p>
<% else %>
<%= link_to "Sign up", signup_path %>
<%= link_to "Log in", login_path %>
<% end %>
My new.html.erb is:
<h1>New User</h1>
<% if current_user %>
<% controller.redirect_to root_url %>
<% else %>
<%= render 'form', user: #user %>
<%= link_to 'Back', login_url %>
<% end %>
My _form.html.erb is:
<%= form_with(model: user) do |form| %>
<% if user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name, "Full Name" %>
<%= form.text_field :nomeUsuario %>
</div>
<div class="field">
<%= form.label :name, "E-mail" %>
<%= form.text_field :email %>
</div>
<div class="field">
<%= form.label :name, "Password" %>
<%= form.password_field :password %>
</div>
<div class="field">
<%= form.label :name, "Password Confirmation" %>
<%= form.password_field :password_confirmation %>
</div>
<div class="field">
<%= form.label :name, "Tipo do Plano" %>
<%= form.select :tipoPlano, ["Gratuito", "Mensal", "Anual"], selected: "Gratuito" %>
</div>
<%= form.hidden_field :indicadoPor, params[:indicadoPor] %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
My user_controller.rb is:
class UsersController < ApplicationController
before_action :set_user, only: %i[ show edit update destroy ]
# GET /users/new
def new
#user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users or /users.json
def create
#user = User.new(user_params)
set_tipoPlano
#user.indicadoPor = params[:indicadoPor]
respond_to do |format|
if #user.save
format.html { redirect_to root_url, notice: "User was successfully created." }
format.json { render root_url, status: :created, location: #user }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1 or /users/1.json
def update
respond_to do |format|
if #user.update(user_params)
set_tipoPlano
format.html { redirect_to root_url, notice: "User was successfully updated." }
format.json { render :show, status: :ok, location: #user }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Only allow a list of trusted parameters through.
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :nomeUsuario, :tipoPlano, :valorPlano, :indicadoPor, :comissaoAcumuladaAtual, :comissaoASerRetirada)
end
def set_tipoPlano
if(#user.tipoPlano == "Gratuito")
#user.valorPlano = 0.0
elsif(#user.tipoPlano == "Mensal")
#user.valorPlano = 49.90
elsif(#user.tipoPlano == "Anual")
#user.valorPlano = 39.90
end
end
end
If you need something else, please let me know! Thank you so much for the help.
ANSWER BELOW
I've fixed it.
I just had to change my form to:
<%= form.hidden_field :indicadoPor, value: params[:indicadoPor] %>
I forgot the =, so the form wasn't being rendered. Also, I've removed the #user.referredBy = params[:referredBy] from my controller. Everything is fine now.
Thank you guys, gals and non-binaries for the help so far!
[:referral]
This is an array with a single value. That value is a symbol :referral.
I'm not sure what type your referredBy column is but it's almost certainly going to complain about being given an array of symbols.
You want
params[:referral]
params is a hash like object containing the params in the url/(and sometimes body). So params[:referral] looks up the :referral symbol in the params hash and returns whatever the user provided.
I am new to spree and ruby on rails. while creating a custom controller in my spree app, I can successfully add link to it in spree admin panel using deface. but when I go to that link, it gives me following error
NoMethodError in Spree::Admin::Societies#new
Showing app/views/spree/admin/societies/_form.html.erb where line #1 raised:
undefined method `societies_path' for #<#<Class:0x007f19cb636898>:0x007f19c5ecacf8>
I don't know from where it is looking for 'societies_path' as I already have updated app/views/spree/admin/societies/new.html.erb to look for 'admin_societies_path', here it is
<%= render 'form' %>
<%= link_to 'Back', admin_societies_path %>
and app/views/spree/admin/societies/_form.html.erb contains
<%= form_for(#society) do |f| %>
<% if #society.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#society.errors.count, "error") %> prohibited this society from being saved:</h2>
<ul>
<% #society.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :address %><br>
<%= f.text_field :address %>
</div>
<div class="field">
<%= f.label :area %><br>
<%= f.text_field :area %>
</div>
<div class="field">
<%= f.label :postcode %><br>
<%= f.number_field :postcode %>
</div>
<div class="field">
<%= f.label :city %><br>
<%= f.text_field :city %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I tried removing link to back also, but it's again giving same error.
config/routes.rb is
mount Spree::Core::Engine, :at => '/'
Spree::Core::Engine.add_routes do
namespace :admin do
resource :societies
end
end
and my app/controllers/spree/admin/societies_controller.rb is
module Spree
module Admin
class SocietiesController < Spree::Admin::BaseController
before_action :set_society, only: [:show, :edit, :update, :destroy]
def index
#societies = Society.all
end
def show
end
def new
#society = Society.new
end
def edit
end
def create
#society = Society.new(society_params)
respond_to do |format|
if #society.save
format.html { redirect_to #society, notice: 'Society was successfully created.' }
format.json { render :show, status: :created, location: #society }
else
format.html { render :new }
format.json { render json: #society.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #society.update(society_params)
format.html { redirect_to #society, notice: 'Society was successfully updated.' }
format.json { render :show, status: :ok, location: #society }
else
format.html { render :edit }
format.json { render json: #society.errors, status: :unprocessable_entity }
end
end
end
def destroy
#society.destroy
respond_to do |format|
format.html { redirect_to societies_url, notice: 'Society was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_society
#society = Society.find(params[:id])
end
def society_params
params.require(:society).permit(:name, :url, :building_number, :address, :area, :postcode, :city, :active, :IsDelete)
end
end
end
end
Any help would be greatly appreciated.
I would suspect that it is this line in _form partial
<%= form_for(#society) do |f| %>
You need to reference the namespace here, so maybe somthing like
<%= form_for([:admin, #society]) do |f| %>
or add your own url
<%= form_for(#society, url: admin_societies_path) do |f| %>
Hi I know this has been asked many times but none of those could help me.
I'm building an online clinic website based on ruby on rails.
When a user wants to sign up it chooses either Doctor or Patient. After that a sign-in form appears.
In DB, there's a general table for users for common attributes like name, gender etc. In that table the user type in set. For Doctor and Patient there are two separate tables for their specific attributes.
Here's the problem!
When signing up I get the error: raise ParameterMissing.new(key)
Here's thee code for doctor_controller.rb:
class DoctorsController < ApplicationController
before_action :set_doctor, only: [:show, :edit, :update, :destroy]
#before_save :set_type
# GET /doctors
# GET /doctors.json
def index
#doctors = Doctor.all
end
# GET /doctors/1
# GET /doctors/1.json
def show
end
# GET /doctors/new
def new
#doctor = Doctor.new
#user=User.new
#user.user_type='2'
end
# GET /doctors/1/edit
def edit
end
# POST /doctors
# POST /doctors.json
def create
#user=User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'Doctor was successfully created.' }
format.json { render :show, status: :created, location: #doctor }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
#doctor = Doctor.new(doctor_params)
respond_to do |format|
if #doctor.save
format.html { redirect_to #doctor, notice: 'Doctor was successfully created.' }
format.json { render :show, status: :created, location: #doctor }
else
format.html { render :new }
format.json { render json: #doctor.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /doctors/1
# PATCH/PUT /doctors/1.json
def update
respond_to do |format|
if #doctor.update(doctor_params)
format.html { redirect_to #doctor, notice: 'Doctor was successfully updated.' }
format.json { render :show, status: :ok, location: #doctor }
else
format.html { render :edit }
format.json { render json: #doctor.errors, status: :unprocessable_entity }
end
end
end
# DELETE /doctors/1
# DELETE /doctors/1.json
def destroy
#doctor.destroy
respond_to do |format|
format.html { redirect_to doctors_url, notice: 'Doctor was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_doctor
#doctor = Doctor.find(params[:id])
#user = User.find(params[:id])
end
def set_type
#user.user_type="2"
end
# Never trust parameters from the scary internet, only allow the white list through.
def doctor_params
params.require(:doctor).permit(:user_id, :doctroNum, :adderess, :sepciality, :records)
end
def user_params
params.require(:user).permit(:user_type, :username, :password, :name, :family, :gender, :phone, :city, :profilepicture)
end
end
and here is the code for signup form:
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :username, "Email" %><br>
<%= f.email_field :username %>
</div>
<div class="field">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :family %><br>
<%= f.text_field :family %>
</div>
<div class="field">
<%= f.label :gender %><br>
<%= f.text_field :gender %>
</div>
<div class="field">
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</div>
<div class="field">
<%= f.label :city %><br>
<%= f.text_field :city %>
</div>
<% end %>
<%= form_for(#doctor) do |f| %>
<% if #doctor.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#doctor.errors.count, "error") %> prohibited this doctor from being saved:</h2>
<ul>
<% #doctor.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :doctroNum %><br>
<%= f.text_field :doctroNum %>
</div>
<div class="field">
<%= f.label :adderess %><br>
<%= f.text_field :adderess %>
</div>
<div class="field">
<%= f.label :sepciality %><br>
<%= f.text_field :sepciality %>
</div>
<div class="field">
<%= f.label :records %><br>
<%= f.text_field :records %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I know it's too much. I'd be really thankful
There is no f.submit button for form_for(#user), so whenever you press the submit button, the form_for(#doctor)'s submit button gets called. Hence, the params that are sent forward, always include doctor, and never include user. But the code in your create method expects params to have user in it: #user = User.new(user_params) - therefore, it is generating param is missing or the value is empty: user.
Apart from it, you are not following the good practices. You controller name is DoctorsController, but you are mixing it with the user's code. You should have two separate controllers: DoctorsController, UsersController, and accordingly two different views.
I have a User model, which has_one prestataire and has_one employeur. Previously on stackoverflow, someone advised me to declare singular resources, like:
resources :users do
resource: employeur
resource: prestataire
end
Instead of:
resources :users do
resources: employeurs
resources: prestataires
end
Thanks to rails, I didn't had to singularize all my controllers and views name files. Yet, when I create a user and am redirected to the employeur form, I get undefined method `user_employeurs_path', which is right since I only have a user_employeur_path. But I didn't ask for the plural in my user controller. Rails indicates that this NoMethodError happens in the first line of my employeur form <%= form_for [#user, #employeur] do |f| %>, where one is redirected when a user is saved.
class UsersController < ApplicationController
#TODO index user doit être suprimé quand inutile pour dev
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
# GET /users/1/edit
def edit
#user = User.find(params[:id])
end
# POST /users
# POST /users.json
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
if params[:commit] == 'Prestataire'
format.html { redirect_to new_user_prestataire_path(user_id: #user), notice: "Renseignez vos informations d'employeur" }
format.json { render action: 'show', status: :created, location: #user }
else
format.html { redirect_to new_user_employeur_path(user_id: #user), notice: "Renseignez vos informations de prestataire" }
format.json { render action: 'show', status: :created, location: #user }
end
else
format.html { render action: 'new' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /users/1
# PATCH/PUT /users/1.json
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update(user_params)
if params[:commit] == 'Prestataire'
format.html { redirect_to new_user_prestataire_path(user_id: #user), notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { redirect_to new_user_employeur_path(user_id: #user), notice: "User was successfully updated." }
format.json { head :no_content }
end
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation, :surname, :forename, :civility, :phone)
end
end
User form:
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :civility, 'Titre de civilité: ' %><br>
<%= f.text_field :civility %>
</div>
<div class="field">
<%= f.label :forename, 'Prénom: ' %><br>
<%= f.text_field :forename %>
</div>
<div class="field">
<%= f.label :surname, 'Nom de famille: ' %><br>
<%= f.text_field :surname %>
</div>
<div class="field">
<%= f.label :email, 'Email: ' %><br>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password, 'Mot de passe: ' %><br>
<%= f.password_field :password, size: 40 %>
</div>
<div class="field">
<%= f.label :password_confirmation, 'Confirmation de mot de passe: ' %><br>
<%= f.password_field :password_confirmation, size: 40 %>
</div>
<div class="field">
<%= f.label :phone, 'Numéro de téléphone: ' %><br>
<%= f.text_field :phone %>
</div>
<div class="actions">
<%= f.submit "Employeur" %>
<%= f.submit "Prestataire" %>
</div>
<% end %>
Employeur form:
<%= form_for [#user, #employeur] do |f| %>
<% if #employeur.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#employeur.errors.count, "error") %> prohibited this employeur from being saved:</h2>
<ul>
<% #employeur.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :siren, 'Siren: ' %><br>
<%= f.text_field :siren %>
</div>
<div class="field">
<%= f.label :societe, 'Société: ' %><br>
<%= f.text_field :societe %>
</div>
<div class="field">
<%= f.label :code_postal, 'Code Postal: ' %><br>
<%= f.text_field :code_postal %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
As for my new.html document for employeur:
<h1>New employeur</h1>
<%= render 'form' %>
Here is what's happening:
when you pass <%= form_for [#user, #employeur] do |f| %>, Rails will connect the objects (#user & #employeur) in the order you passed and the then append path to it. So this becomes user_employeurs_path. by convention it will pluralize your the last object (employeur) to infer your controller's name. that's how it gets: user_employeurs_path
so you would either have to pluralize your controller's resources to follow the convention. Or pass url to your path:
<%= form_for [#user, #employeur], url: user_employeur_path do |f| %>
I believe you can use url parameter in this case. Try something like:
<%= form_for [#user, #employeur], url: user_employeur_path do |f| %>
...
I have a admin section and inside the admin i have, Finalist and Images.
Im using, ruby 1.8.7-p249 and Rails 3.1.2
# model image.rb
class Admin::Image < ActiveRecord::Base
belongs_to :finalist
...
end
# model finalist.rb
class Admin::Image < ActiveRecord::Base
has_many :images
...
end
My ImagesController:
def new
#admin_finalist = Admin::Finalist.find(params[:finalist_id])
#admin_image = #admin_finalist.images.build
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #admin_image }
end
end
def edit
#admin_finalist = Admin::Finalist.find(params[:finalist_id])
#admin_image = #admin_finalist.images.find(params[:id])
end
def create
#admin_finalist = Admin::Finalist.find(params[:finalist_id])
#admin_image = #admin_finalist.images.new(params[:admin_image])
respond_to do |format|
if #admin_image.save
format.html { redirect_to admin_finalist_images_path(#admin_finalist) }
format.json { render :json => #admin_image, :status => :created, :location => #admin_image }
else
format.html { render :action => "new" }
format.json { render :json => #admin_image.errors, :status => :unprocessable_entity }
end
end
end
def update
#admin_finalist = Admin::Finalist.find(params[:finalist_id])
#admin_image = #admin_finalist.images.find(params[:id])
respond_to do |format|
if #admin_image.update_attributes(params[:admin_image])
format.html { redirect_to admin_finalist_images_path(#admin_finalist) }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => #admin_image.errors, :status => :unprocessable_entity }
end
end
end
And my Images _form.html.erb:
<%= form_for([#admin_finalist, #admin_image]) do |f| %>
<% if #admin_image.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#admin_image.errors.count, "error") %> prohibited this admin_image from being saved:</h2>
<ul>
<% #admin_image.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :file %>
<%= f.file_field :file %>
</div>
<%- unless #admin_image.new_record? || !#admin_image.file? -%>
<div class="field">
<%= f.label :remove_file, "Remover?" %>
<%= f.check_box :remove_file %>
</div>
<%- end -%>
<div class="field">
<%= f.label :url %>
<%= f.text_field :url, :placeholder => "http://" %>
</div>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="actions">
<%= image_submit_tag("button/save.png") %>
<%= link_to image_tag("button/back.png"), admin_finalist_images_path %>
</div>
<% end %>
Everything seems perfect, but im getting this error when im trying to add an image to finalist at admin/finalists/1/images/new.
Showing .../app/views/admin/images/_form.html.erb where line #5 raised:
undefined method `admin_finalist_admin_images_path' for #<#<Class:0x102da0068>:0x102d9a870>
So, i tryed to tell rails to use a particular url:
<%= form_for([#admin_finalist, #admin_image], :url => admin_finalist_image_path(#admin_finalist.id, #admin_image)) do |f| %>
Saddly, this work only for editing. When i try to edit i get this error message:
No route matches {:controller=>"admin/images", :finalist_id=>1, :id=>nil, :action=>"show"}
And if i wanna create i need to do:
<%= form_for([#admin_finalist, #admin_image], :url => admin_finalist_images_path) do |f| %>
And if i try to edit i get this message:
No route matches [PUT] "/admin/finalists/1/images"
I dont know what to do... I tried everything without success, if anyone can help me would be much appreciated.
EDIT
The problem was that my models was namespaced. So, i rewrite all the app to fix this, and thats running normally.
[]`s