ActiveModel::ForbiddenAttributesError using an older version of ruby? [duplicate] - ruby

This question already has answers here:
ActiveModel::ForbiddenAttributesError in PasswordResetsController#update
(3 answers)
Closed 8 years ago.
I am creating a blog using ruby on rails. I am following a tutorial that is using an older version on rails. I am trying to post comments about the blog post on the same page. whenever i hit the submit button i get this error message.
ActiveModel::ForbiddenAttributesError
Extracted source (around line #44):
def create
#post = Post.find(params[:post_id])
#comment= #post.comments.new(params[:comment])
respond_to do |format|
if #comment.save
Here is my code inside my controller
def create
#post = Post.find(params[:post_id])
#comment= #post.comments.build(params[:comment])
respond_to do |format|
if #comment.save
format.html { redirect_to #post, notice: 'Comment was successfully created.' }
format.json { render json: #post, status: :created, location: #comment }
else
format.html { render action: "new" }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
Thanks for the help

I guess you are using Rails 4. If so, the needed parameters must be marked as required in controller.
You can refer http://stackoverflow.com/questions/17868427/rails-4-activemodelforbiddenattributeserror

Related

rails update action not working

I have following table in database and also the model created for it.
|id |name |description |created_date |updated_date |
-----------------------------------------------------------------------
|1 |HELLO |greeting |2017-09-28 18:51:51 |2017-09-28 18:51:51|
model.rb
class Person < ApplicationRecord
has_many :person_activities
validates :name, uniqueness: true
end
I want to create update action in controller. It will update the name and description based on the name passed. e.g i want to update the name HELLO to HI. How can i create update action for that?
I tried following update action in controller but it wont hit the update action
def update
byebug
redirect_to Person.find(name: params[:id]).tap { |person|
person.update!(person_params)
}
end
private
def person_params
params.require(:person).permit(:name)
end
routes.rb
resources :person, only: [:index, :show, :create, :update, :destroy], defaults: { format: :json }
Tried testing like this http://localhost:1111/person/HELLO and passing { name: 'HI'} in body params. I am using postman for testing.
You can modify your model, something like this:
class Person< ActiveRecord::Base
before_save :change_name
private
def change_name
self.name="HI" if self.name=="HELLO"
end
end
To answer this properly we would need to understand the logic of how creating a new record with name = "HELLO" would need to be set to "HI". Do you have a lookup table for this logic or is it hardcoded?
The easiest thing I could think of is you can change the value of the passed parameter before doing the update by setting the value of the parameter. E.G.
params["name"] = "HI"
So when you do a person.update it will use the "name" param set to "HI".
Then you could do this in a
def update
respond_to do |format|
params["name"] = "HI"
if #person.update(person_params)
format.html { redirect_to #person, notice: 'Person was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
You could also do the update then just set the value after the update:
def update
respond_to do |format|
if #person.update(person_params)
#person.name = "HI"
#person.save
format.html { redirect_to #person, notice: 'Person was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
From postman you need to call login action first. So it will create a session in postman and then you can call update action.

What to use instead of after_commit in controller in Rails 5?

Today I tried to use a wonderful callback :after_commit which triggers when the object is written to database, however, I've got the error message from Rails:
ActionController::RoutingError (undefined method `after_commit' for ImagesController:Class
Did you mean? after_action):
Well, that was embarassing! And it seems like this callback was deprecated!
Looking through search, I tried to use :after_create_commit, which gave me the same error.
The third step was to try :after_action. Here goes the question:
How to make it work the same way as :after_commit?
I've already tried apidock.com - it's really minimal! Also I've tried api.rubyonrails.org - it is saying about blocks, but I'm not a ruby ninja to understand it. So I really apprecite if you could spill some light on it!
ImagesController:
class ImagesController < ApplicationController
after_create_commit :take_image_to_album
def take_image_to_album
if check_album
add_inner_to_album(#image)
end
end
def create
#image = Image.create(image_params.merge(:user_id => current_user.id)
respond_to do |format|
unless #image.save
format.html { render :show, notice: "Error!" }
format.json { render json: #image.errors, status: :unprocessable_entity }
else
format.html
format.json { render :show, status: :ok, location: #image }
end
end
end
...
def add_inner_to_album(image)
contents = #album.content
contents << [image.id, image[:imageup], false]
#album.update(:content => contents)
end
end
The after_commit method is only for models. In the controllers family, you have after_action, that will be executed after the action of the controller is finished.
For example, the after_action in a controller works like this:
class UsersController < ApplicationController
after_action :log_activity, only: :show
# GET v3/users/:id
def show
render status: :ok,
json: { id: current_user.id, name: current_user.name }
end
def log_activity
current_user.update(last_activity_at: Time.current)
end
end
The log_activity method is executed after responding the request.
In the after_action :log_activity, only: :show, with only you can specify after which actions log_activity will run. If you do not specify any, it will run after every action defined in the controller.

param is missing or the value is empty: category

Im trying to create a new Category based on the title of the 'grow' that im creating (for a garden management tool'
But Im getting the following error:
'param is missing or the value is empty: category'
[edit] this is how the code is fixed. As per the suggestion in the comments:
remove the #grow = Grow.new(grow_params.merge(category: Category.create(cat_params)))
and replace with #grow = Grow.new(grow_params)
and in the Grow model add
after_create do
Category.create(name: self.title)
end
and its fixed.
class GrowsController < ApplicationController
before_action :set_grow, only: [:show, :edit, :update, :destroy]
def index
#grows = Grow.all
end
def show
end
def new
#grow = Grow.new
end
def edit
end
def create
#grow = Grow.new(grow_params.merge(category: Category.create(cat_params)))
respond_to do |format|
if #grow.save
format.html { redirect_to #grow, notice: 'Grow was successfully created.' }
format.json { render :show, status: :created, location: #grow }
else
format.html { render :new }
format.json { render json: #grow.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /grows/1
# PATCH/PUT /grows/1.json
def update
respond_to do |format|
if #grow.update(grow_params)
format.html { redirect_to #grow, notice: 'Grow was successfully updated.' }
format.json { render :show, status: :ok, location: #grow }
else
format.html { render :edit }
format.json { render json: #grow.errors, status: :unprocessable_entity }
end
end
end
# DELETE /grows/1
# DELETE /grows/1.json
def destroy
#grow.destroy
respond_to do |format|
format.html { redirect_to grows_url, notice: 'Grow was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_grow
#grow = Grow.find(params[:id])
end
def cat_params
params.require(:category).permit(:name)
end
def grow_params
params.require(:grow).permit(:title, :notes, :category_id)
end
end
I simply want to pass in the grow.title to new category name
However im not sure how to implement it.
In your create method leave the statement to be
#grow = Grow.new(grow_params)
and in your Grow model, write an after_create callback
within which you create your Category like Category.create(name: self.title)

rails parameters not found

I am developing application using stripe for payment. I have Plan and Subscription model in my app. Plan has many subscriptions and subscription belongs t plan. On plans index page i have plans listings and user can click on any of the plans
<td><%=link_to plan.name, new_subscription_path(:plan_id => plan.id) %></td>
and in my subscription controller i have this
def new
#plan = Plan.find(params[:plan_id])
#subscription = #plan.subscriptions.new
end
def create
#plan = Plan.find(params[:plan_id])
#subscription = #plan.subscriptions.new(subscription_params)
respond_to do |format|
if #subscription.save
format.html { redirect_to #subscription, notice: 'Subscription was successfully created.' }
format.json { render :show, status: :created, location: #subscription }
else
format.html { render :new }
format.json { render json: #subscription.errors, status: :unprocessable_entity }
end
end
end
I am trying to build subscription on particular plan but i am getting this error
Couldn't find Plan with 'id'=
You should update your config/routes.rb to look like:
resources :plans do
resources :subscriptions
end
And later in your template, you should use new_plan_subscription_path like:
<td><%=link_to plan.name, new_plan_subscription_path(:plan_id => plan.id) %></td>
This should help!
Good luck!

How to connect Devise User to ProfilesController Ruby on Rails 4

Before I begin, let me say that I have two different devise user models.
I began removing the unnecessary methods from the scaffold_controller, because devise handles certain actions.
I'm trying to route to the current_user profile page, but I get an error every time I try to add the link in my navbar <%= 'My Profile', current_user %> doesn't work in this case. I plan to setup the associations as soon as I finish hooking up these controllers.
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
#user = User.find(params[:id])
respond_to do |format|
format.html
format.json {render :json => #user }
end
end
# GET /profiles/1/edit
def edit
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
#profile = Profile.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params[:profile]
end
end
profiles GET /profiles(.:format) profiles#index
POST /profiles(.:format) profiles#create
new_profile GET /profiles/new(.:format) profiles#new
edit_profile GET /profiles/:id/edit(.:format) profiles#edit
profile GET /profiles/:id(.:format) profiles#show
PATCH /profiles/:id(.:format) profiles#update
PUT /profiles/:id(.:format) profiles#update
DELETE /profiles/:id(.:format) profiles#destroy
Assuming (such as bad thing to do), that you have already created the profile while creating the user ( since there is no create action in the controller ) and that a profile belongs_to a user, then this should work:
<%= link_to "My Profile", current_user.profile %>
Generally, I would get my associations set up properly before I even look at the controllers.

Resources