Reputation: 971
would someone be able to help me understand this error. I am trying to create a contact form in rails following the building web apps tutorial. I followed the steps to generate a message scaffold. I then amended my routes. Next it said to put this into the messages controller show action.
if @message.save
flash[:notice] = 'Thanks for Your Message'
format.html { redirect_to root_path }
I have done this and i am getting the following error ActiveModel::ForbiddenAttributesError in MessagesController#create ActiveModel::ForbiddenAttributesError
This is my message controller file
class MessagesController < InheritedResources::Base
def show
if @message.save
flash[:notice] = 'Thanks for Your Message'
format.html { redirect_to root_path }
end
end
end
My routes file is as follows
# devise_for :users
resources :products do resources :orders, only: [:new, :create] #tells rails needs product id number end
# get 'pages/payment'
get 'home/about'
get 'messages/new'
get 'seller' => "products#seller"
get 'sales' => "orders#sales"
get 'static_pages/productlanding'
get "content/veg"
get "content/fruit"
get "content/mix"
get 'subscriptions/new'
root 'static_pages#home'
Upvotes: 5
Views: 22382
Reputation: 482
I was facing this same error. The fix was to make the params function name same as the root tag of the post json like below
Post json {"jobseeker_certificate":{"id":-1,"name":"First Class Medical Certificate","institute":"GACA","attachment":null}}
In Controller i changed jobseeker_aircraft_type_ratings_params to jobseeker_certificate_params
def jobseeker_certificate_params
params.require(:jobseeker_certificate).permit(:aircraft, :total_time, :pilot_in_command,
:co_pilot, :rating_expiry_date, :from, :to, :jobseeker_id, :grade, :institute, :attachment, :name,
:from, :to, :jobseeker_id, :grade, :institute, :attachment, :name, :sector_id, :certificate_type,
:details, :certificate_type, :details)
end
Upvotes: 0
Reputation: 76774
Why are you saving in the show action?
--
Params
The ForbiddenAttributes
error stems from the strong_params
functionality of Rails.
When saving data, you're meant to pass the params through to your model through a strong_params
method. This is typically achieved with the following setup:
#app/controllers/messages_controller.rb
class MessagesController < ApplicationController
def show
@message = Message.find(params[:id])
end
def new
@message = Message.new
end
def create
@message = Message.new(message_params)
@message.save
end
private
def message_params
params.require(:message).permit(:your, :message, :params)
end
end
This is how your controller
should really be constructed. Your error, I believe, is caused by your lack of params to pass through to the attributes in your model (hence your call to @save
resulting in trying to populate your model with non-data).
Upvotes: 14
Reputation: 971
i have managed to sort this with the following! Thanks for all the help
class MessagesController < ApplicationController
before_action :set_message, only: [:show, :edit, :update, :destroy]
# GET /messages
# GET /messages.json
def index
@messages = Message.all
end
# GET /messages/1
# GET /messages/1.json
def show
end
# GET /messages/new
def new
@message = Message.new
end
# GET /messages/1/edit
def edit
end
# POST /messages
# POST /messages.json
def create
@message = Message.new(message_params)
respond_to do |format|
if @message.save
flash.now[:notice] = 'Thank you for your message!'
format.html { redirect_to root_path }
format.json { render :show, status: :created, location: @message }
else
format.html { render :new }
format.json { render json: @message.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /messages/1
# PATCH/PUT /messages/1.json
def update
respond_to do |format|
if @message.update(message_params)
format.html { redirect_to @message, notice: 'Message was successfully updated.' }
format.json { render :show, status: :ok, location: @message }
else
format.html { render :edit }
format.json { render json: @message.errors, status: :unprocessable_entity }
end
end
end
# DELETE /messages/1
# DELETE /messages/1.json
def destroy
@message.destroy
respond_to do |format|
format.html { redirect_to messages_url, notice: 'Message was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_message
@message = Message.find(params[:id])
end
.
def message_params
params.require(:message).permit(:name, :email, :company, :phone, :subject, :body)
end
end
Upvotes: 1
Reputation: 232
Strange. You execute saving method in "show" method of controller which responsible for showing up the content on the separate page.
You should replace as following:
def create
if @message.save
flash[:notice] = 'Thanks for Your Message'
format.html { redirect_to root_path }
end
end
Upvotes: 1