Why Rails cannot add a new record to database? - ruby-on-rails

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.

Related

Not able to update data in database form

I am getting error - undefined method collect for nil:NilClass, but I am able to render option list from another database table, and also able to save data in stage table but not able to update it.
I am rendering option list form responsibility table in stage form field responsibility option and saves that option into stage table.
stages_controller.rb
def index
redirect_to project_path(#project)
end
def show
end
def new
#stage = Stage.new
#responsibilities = #project.responsibilities
end
def edit
end
def create
#responsibilities = #project.responsibilities
#stage = #project.stages.build(stage_params)
respond_to do |format|
if #stage.save
format.html { redirect_to project_path(#project), notice: 'Stage was successfully created.' }
format.json { render :show, status: :created, location: #stage }
else
format.html { render :new }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def update
#responsibilities = #project.responsibilities
respond_to do |format|
if #stage.update(stage_params)
format.html { redirect_to project_stages_url, notice: 'Stage was successfully updated.' }
format.json { render :show, status: :ok, location: #stage }
else
format.html { render :edit }
format.json { render json: #stage.errors, status: :unprocessable_entity }
end
end
end
def destroy
#stage.destroy
respond_to do |format|
format.html { redirect_to project_stages_url, notice: 'Stage was successfully deleted.' }
format.json { head :no_content }
end
end
private
def set_stage
#stage = Stage.find(params[:id])
end
def find_project
#project = Project.find(params[:project_id])
end
your edit method is empty, so #responsibility has no content (null), you can put some code for example (from your other method)
def edit
#project = Project.find(params[:id])
#responsibilities = #project.responsibilities
...
end
The issue here is that #responsibilities is not defined in your partial.
You should pass the local variable to the partial like this -
<%= render partial: "form", locals: {responsibilities: # responsibilities} %>
and then you can use responsibilities inside the form partial
More about passing variable to partials

change behaviour of Create if record with same attribute exists

I'm building an app like reddit where you add a Submission to a specific user page. Submission has a few attribute including an attribute called url.
I want to check when adding a new submission if already a submission with that same url exists for that specific page, and if it exist, vote for it instead of creating it as a new submission. If not, just add it as a new submission. I'm using the act_as_votable gem here.
Here is the create method:
def create
#user = User.friendly.find(params[:user_id])
#submission = #user.submissions.new(submission_params)
#submission.member_id = current_user.id
#submission.creator_id = #user.id
#submission.is_viewed = false
#submission.get_thumb_and_title_by_url(#submission.url)
respond_to do |format|
if #submission.save
format.html { redirect_to #user, notice: 'Submission was
successfully created.' }
format.json { render :show, status: :created, location: #submission }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
you should take a look at https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by and https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_initialize_by
Now on your code we can make changes like
def create
#user = User.friendly.find(params[:user_id])
#submission = #user.submissions.find_or_initialize_by(submission_params)
if #submission.id.present?
# What to do if the record exists
else
# if its a new record
#submission.member_id = current_user.id
#submission.creator_id = #user.id
#submission.is_viewed = false
#submission.get_thumb_and_title_by_url(#submission.url)
end
respond_to do |format|
if #submission.save
format.html { redirect_to #user, notice: 'Submission was
successfully created.' }
format.json { render :show, status: :created, location: #submission }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I hope that this can put you on the right track
Happy Coding

Rails mailer: create object and access the id of the object inside a mailer view template

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

Params Error (ActiveModel::ForbiddenAttributesError)

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.

ruby on rails redirect_to parameter passage not working

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.

Resources