I'm getting a "ActiveModel::ForbiddenAttributesError in CommentsController#create" with highlights in "#comment = #post.comments.build(params[:comment])"
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 action: 'show', status: :created, location: #comment }
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
in the tutorial video the coder puts this in and works perfect yet when I post this it gives an error. I have checked through the code and cannot to seem to see whats wrong. Thanks in advance!
Looking at the error, I am assuming that you must be using Rails 4. Strong Parameters were introduced in Rails 4. See Strong Parameters reference here.
Replace
#comment = #post.comments.build(params[:comment])
with
#comment = #post.comments.build(comment_params)
Add a private method in your controller as follows:
def comment_params
params.require(:comment).permit(:attr1, :attr2,...)
end
where
:attr1, :attr2 would be the attributes name of Comment model.
Related
I want to save the user ID who edited the article on my aplication. I'm using Devise gem.
here's the update method in article controller
def update
#article = Article.find(params[:id])
updated = #article.update(article_params) do |article|
article.editor_id = current_user.id
end
if updated
format.html { redirect_to #article, notice: 'Article was successfully updated.' }
format.json { render :show, status: :ok, location: #article }
else
format.html { render :edit }.s: :unprocessable_entity }
end
end
update process is success but it didn't save the user id. And plus, how to save the user id only if the article content changed? Any advice?
with direction from #sujan i change my code to this. i'm removing the update variable to make it more simpler
def update
#article.assign_attributes(article_params)
if #article.content_changed?
#article.editor_id = current_user.id
end
respond_to do |format|
if #article.save
format.html { redirect_to #article, notice: "Article succesfully updated" }
format.json { render :show, status: :ok, location: #article }
else
format.html { render :edit }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
You need to save the article after assigning the editor_id. Try,
updated = #article.update(article_params) do |article|
article.editor_id = current_user.id
article.save
end
or better,
updated = false
#article.assign_attributes(article_params)
if #article.changed?
#article.editor_id = current_user.id
updated = #article.save
end
This will update the article only if there are changes.
Refs:
assign_attributes
changed
I think you should check out act as versioned: https://github.com/technoweenie/acts_as_versioned
The other way is that you create another model for it, which will logs the changes, and who did them. Like ArticleLog (article_id, user_id, changed_attr, prev_val).
Write a hook to create ArticleLog on update of Article, if the attribute you want to log is changed.
https://guides.rubyonrails.org/active_record_callbacks.html#updating-an-object
I hope I helped you! :)
I'm creating and object inside a controller:
def create
#item = Item.new(item_params)
if #item.save
respond_to do |format|
format.html { redirect_to index_path, notice: "Created"}
format.json { render :'shows/show', status: :created, location: #item }
end
ModelMailer.delay.new_post(#user)
else
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
this is the mailer method:
def new_post(user)
#user = User.find(user.id)
attachments.inline["logo.png"] = File.read("#{Rails.root}/app/assets/images/logo.png")
mail(:to => #follow.email,
:subject => "Created a new post")
end
I would like to add the item.id thats is created to the mailer so I can access it in the email view template. Any ideas on how to implement this?
Just pass it. I don't actually see where you save the record so presumably your create example is incomplete, but once you have that working you can do...
ModelMailer.new_post(#user, #item.id).deliver_later
Then on the mailer
def new_post(user, item_id)
#item_id = item_id
The #item_id will be available in the view.
And to fix your controller create method (which is still wrong), it should be...
def create
#item = Item.new(item_params)
if #item.save
respond_to do |format|
format.html { redirect_to index_path, notice: "Created"}
format.json { render :'shows/show', status: :created, location: #item }
ModelMailer.delay.new_post(#user, #item.id)
end
else
respond_to do |format|
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
I'm using PostgreSQL. I have the next form on /main URL(localhost:3000/main):
=form_for(#car) do |b|
.col-xs-2= b.text_field(:type, class: "form-control", placeholder: "Type")
= b.submit('Buy', class: "btn btn-default")
In my Controller:
def main
#car = Car.new
end
def new
#car = Car.new
end
def create
#car = Car.new(car_params)
respond_to do |format|
if #car.save
format.html { redirect_to #car, notice: 'Car was successfully ordered.' }
format.json { render :show, status: :created, location: #car }
else
format.html { render :new }
format.json { render json: #car, status: :unprocessable_entity }
end
end
end
where
def car_params
params.require(:car).permit(:type)
end
I checked my code 100 times and it seems everything okay, but I cannot add a new record to my database table. Can anyone help me why it happens? What is the problem in my code?
You forgot to save the car. Although you declare and set the object, you forgot to save it in the database.
You should do it by adding the following line:
#car.save
in the create action
A few things missing your create method. Need to add ".new" where the car variable is being set, and then also ".save" where the if statement is, I believe that should do it.
Create method should be like below
def create
#car = Car.new(car_params)
respond_to do |format|
if #car.save
format.html { redirect_to #car, notice: 'Car was successfully ordered.' }
format.json { render :show, status: :created, location: #car }
else
format.html { render :new }
format.json { render json: #car, status: :unprocessable_entity }
end
end
#car = Car(car_params) is not correct.
You need to do #car = Car.new(car_params)
First thing you need to do is to replace this line in your create method.
#car = Car(car_params)
with this line
#car = Car.new(car_params)
Because we need to initialize the record of car with the params permitted. After that you have to call #car.save which will return a boolean.
So you can check it in if condition like
if #car.save
Hope this solves your problem.
I'm getting the following ActiveModel::ForbiddenAttributesError when creating a comment on my app.
The error message precise that the problem comes from line 7 in my Comments Controller file: #comment = #pin.comments.create(params[:comment])
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
before_filter :authenticate_user!
def create
#pin = Pin.find(params[:pin_id])
#comment = #pin.comments.create(params[:comment])
respond_to do |format|
if #comment.save
format.html { redirect_to #pin, notice: 'Comment was successfully created.' }
format.json { render json: #comment, status: :created, location: #comment }
else
format.html { render action: "new" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
private
def comment_params
params.require(:comment).permit(:body, :pin_id)
end
end
here is the comment model
class Comment < ActiveRecord::Base
belongs_to :pin
end
Any help with this error message?
You should replace this line with
#comment = #pin.comments.create(comment_params)
Also, putting pin_id in permitted parameters is unnecessary (since you create comment through #pin.comments association) and possibly unsafe (user could associate comment with other Pin).
My controller file looks like this:
class QuotesController < ApplicationController
def show
#quote = Quote.find(params[:id])
#popup = params[:popup]
respond_to do |format|
if #popup.present?
format.html { render layout: false }
else
format.html
end
format.json { render json: #quote }
end
end
def create
#quote = Quote.new(params[:quote])
respond_to do |format|
if #quote.save
format.html { redirect_to #quote, notice: "Quote was successfully created.", popup: "1" }
format.json { render json: #quote, status: :created, location: #quote }
else
format.html { render action: "errors", layout: false }
format.json { render json: #quote.errors, status: :unprocessable_entity }
end
end
end
end
If I visit http://localhost:3000/quotes/1?popup=1 -- the view correctly displays without application_layout
However, if I am coming from the CREATE action, it seems ?popup=1 is never being appended to the URL - and therefore the application_layout is displaying when it should not be
I thought that adding popup: "1" to the redirect_to line was supposed to pass a param via GET
Can anyone see what I am missing?
Thanks
Edit: tried this on my machine and it worked:
{ redirect_to quote_path(#quote, :popup => "1"), notice: "Quote was successfully created." }
Try #quote_url(:popup=>1) I guess it will work.