Nested model doesn't update - ruby-on-rails

I have two models: PointPage and PointPageClass, which belongs_to :point_page. When user create PointPage rails creates several (now there're 6 of them) PointPageClasses in database. I need to edit all of them on PointPage edit page. So, I'm using nested attributes in controller and fields_for in view.
point_page_form
<%= form_for #point_page, role: 'form' do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
... # some other PointPage fields
<% #point_page.point_page_classes.each do |class| %>
<%= f.fields_for :point_page_classes do |builder| %>
<div class="row">
<div class="col-lg-6">
<%= builder.text_field :distance_price, class: 'form-control' %>
</div>
<div class="col-lg-6">
<%= builder.text_field :show_price, class: 'form-control' %>
</div>
</div>
<% end %>
<% end %>
<%= f.submit 'Save', class: 'btn btn-default' %>
<% end %>
point_page_controller
def update
#point_page = PointPage.find(params[:id])
if #point_page.update_attributes(point_page_params)
respond_to do |format|
format.html { redirect_to new_point_path }
format.js
end
end
end
private
def point_page_params
params.require(:point_page).permit(:name, :url, :article,
point_page_classes_attributes: [:distance_price, :show_price])
end
So, I've added in point_page_controller PointPageClass attributes, but when I save the changes, it only saves changes for PointPage, but not for PointPageClass (distance_price and show_price).
Thanks for any help!

One of the problem could be not permitting the :id in the point_page_params.For the update to take place you need to permit the :id.
Try changing your point_page_params to like this
def point_page_params
params.require(:point_page).permit(:id,:name, :url, :article,point_page_classes_attributes: [:id,:distance_price, :show_price])
end

Related

Using validations and pluralize in views to show errors count for forms rails 7

i am trying to display a message for whenever someone does not fill the form completely and press the submit button!
Example: when someone clicks the submit button without filling the Name and Email field in the form, it should display
2 Errors Prohibited from submitting the form!
. Name can't be blank
. Email can't be blank
but it is not being displayed whenever we submit the form with empty fields
can someone explain me the reason why it is not working?
Orders_controller.rb
class OrdersController < ApplicationController
# GET to /orders/new
def new
#order = Order.new
end
# POST to /orders
def create
#order = Order.new(order_params)
respond_to do |format|
if #order.save!
format.html{ redirect_to root_url, notice: "Order Succesfully Submitted!" }
else
format.html{ render :new, status: :unprocessable_entity }
end
end
end
private
def order_params
params.require(:order).permit(:first_name, :last_name, :phone_number, :email, :paper_size, :color, :paper_style, :quantity, :description, files: [] )
end
end
_form.html.erb (i already rendered the partial in new.html.erb by <%= render 'form', order: #order%>
<div class="container">
<h1 class="text-center">Order From Home!</h1>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<%= form_with(model: order) do |f| %>
<% if order.errors.any? %>
<div style="color: red">
<h3><%= pluralize(order.errors.count,"errors")%> Prohibited from submitting the form! <br/>
All Fields Are Required!</h3>
<ul>
<% order.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label :first_name%>
<%= f.text_field :first_name, class:"form-control" %><br/>
<%= f.label :last_name %>
<%= f.text_field :last_name, class:"form-control" %><br/>
<%= f.label :phone_number %>
<%= f.text_field :phone_number, class:"form-control" %><br/>
<%= f.label :email %>
<%= f.text_field :email, class:"form-control" %><br/>
<%= f.label :files %>
<%= f.file_field :files, multiple: true %><br/>
<%= f.label :paper_size %>
<%= f.select :paper_size, ['A4', 'B4'], { prompt: 'Select' }, class:'form-select' %><br/>
<%= f.label :color %>
<%= f.select :color, ['Black & White', 'Color'], { prompt: 'Select' }, class:'form-select' %><br/>
<%= f.label :paper_style %>
<%= f.select :paper_style, ['Black to Back', 'Side to Side'], { prompt: 'Select' }, class:'form-select' %><br/>
<%= f.label :quantity %>
<%= f.number_field :quantity, class:'form-control' %><br/>
<%= f.label :description %>
<%= f.text_area :description, class:"form-control" %><br/>
<div class="btn-order">
<%= f.submit %>
</div>
<% end %>
</div>
</div>
</div>
#order.save! raises validation errors. You don't need bang method if you want to render such errors, just use #order.save instead
form_with sends XHR request. If you need to render something, you can disable Turbo for this form
<%= form_with(model: order, data: { turbo: false }) do |f| %>

How do i make one form for two related models?

I want to write data for 2 different models that are related to each other like this:
class Post < ActiveRecord::Base
has_many :roads
accepts_nested_attributes_for :roads, :allow_destroy => true
end
class Road < ActiveRecord::Base
belongs_to :post
end
Of course de roads table has a "post_id column". My form_for in the post view looks like this
<%= form_for #post do |f| %>
<div class="form-group">
<%= f.label :Tu_Nombre %>
<%= f.text_field :creador, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :año %> (Cuando fue tu experiencia?)
<%= f.text_field :año, class: "form-control" %>
</div>
<div class="form-group">
<%= fields_for :roads do |r| %>
<%= r.label :principio %> (desde?)
<%= r.text_field :principio, class: "form-control" %>
<%= r.label :final %> (hasta?)
<%= r.text_field :final, class: "form-control" %>
<% end %>
</div>
<div class="form-group">
<%= f.label :historia %> (Cuentanos la historia de tu viaje!)
<%= f.text_area :historia, class: "form-control", size: "50x15" %>
</div>
<div>
<%= f.submit class: "btn btn-success" %>
</div>
<% end %>
Finally my posts_controller create method
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post, notice: 'Post was successfully created.'
else
render :new
end
end
with the private
def post_params
params.require(:post).permit(:historia, roads_attributes: [:pricipio, :final, :post_id])
end
The post is submitted and if i check the console all the atributes for post has been saved but the ones for road, has not. How can i use just one form two make records for these two models and that the post_id gets registered so i can relate the tables?
Thanks a lot!!
Update your posts_controller new method to include .build
def new
#post = Post.new
#post.roads.build
end
Please read the Nested Forms in Form Helpers chapter of Rails Guide. You could use fields_for to build the nested attributes form for your roads and permit nested attributes like the example. Below is an example from rails guide, you could try and figure it out yourself.
_form.html.erb
<%= form_for #person do |f| %>
Addresses:
<ul>
<%= f.fields_for :addresses do |addresses_form| %>
<li>
<%= addresses_form.label :kind %>
<%= addresses_form.text_field :kind %>
<%= addresses_form.label :street %>
<%= addresses_form.text_field :street %>
...
</li>
<% end %>
</ul>
<% end %>
permit nested attributes in people_controller.rb
def person_params
params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street])
end
Attach your fields_for to the parent form builder like so:
<%= f.fields_for :roads do |r| %>

Update feature does not update post but creates a new post

I've been creating a system where I create these entries but the problem is when I tried to create the edit feature, it does not update the post but creates a new one.
My controller file looks like this:
class BetsController < ApplicationController
def new
#bet = Bet.new
end
def create
#bets = Bet.new(bet_params)
if #bets.save
flash[:success] = 'Bet Successfull Logged.'
redirect_to new_bet_path
else
flash[:danger] = 'Error, Bet has not been logged. Try again mate.'
redirect_to new_bet_path
end
end
def show
#bet = Bet.find(params[:id])
end
def edit
#bet = Bet.find(params[:id])
end
def update
#bet = Bet.find(params[:id])
if #bet.update_attributes(bet_params)
flash[:success] = "Bet Updated!"
redirect_to bet_path(params[:id])
else
render action: :edit
end
end
private
def bet_params
params.require(:bet).permit(:bet_placed, :game, :units_placed, :odds, :profit_or_loss)
end
end
And also the form that is submitting looks like this:
<%= form_for :bet, url: bets_path, :html => { :multipart => true } do |f| %>
<p class="form-group">
<%= f.label :bet_placed %><br>
<%= f.text_field :bet_placed, class: 'form-control' %>
</p>
<p class="form-group">
<%= f.label :game %><br>
<%= f.text_field :game, class: 'form-control' %>
</p>
<p class="form-group">
<%= f.label :units_placed %><br>
<%= f.text_field :units_placed, class: 'form-control' %>
</p>
<p class="form-group">
<%= f.label :odds %><br>
<%= f.text_field :odds, class: 'form-control' %>
</p>
<p class="form-group">
<%= f.label :profit_or_loss %><br>
<%= f.text_field :profit_or_loss, class: 'form-control' %>
</p>
<%= f.submit 'Update Profile', class: 'btn btn-default' %>
<% end %>
The way your form is currently setup, it will always hit the create action. If you change your form_for to the following it should work
<%= form_for #bet do |f| %>
...
<% end %>
You shouldn't need multipart => true either since your form doesn't have any file inputs.
According to the rails natural routing the path bets_path always goes to the create method. As update needs an id, and you are not giving it, it goes to create.
Change the form to,
<%= form_for #bet, :html => { :multipart => true } do |f| %>
<p class="form-group">
<%= f.label :bet_placed %><br>
<%= f.text_field :bet_placed, class: 'form-control' %>
</p>
....................
<p class="form-group">
<%= f.label :profit_or_loss %><br>
<%= f.text_field :profit_or_loss, class: 'form-control' %>
</p>
<%= f.submit 'Update Profile', class: 'btn btn-default' %>
<% end %>
For reference,
HTTPVerb Path controller#Action Named Helper
GET /bets bets#index bets_path
GET /bets/new bets#new new_bet_path
POST /bets bets#create bets_path
GET /bets/:id bets#show bet_path(:id)
GET /bets/:id/edit bets#edit edit_bet_path(:id)
PATCH/PUT /bets/:id bets#update bet_path(:id)
DELETE /bets/:id bets#destroy bet_path(:id)

ActionController “No explicit conversion of Symbol into Integer” for new record in Rails 4.2.1

I'm trying to create #booking and #booking.build_passenger in form_for with nested attributes in Rails 4.2.1
The error I get:
As you see in the console at the bottom of the image:
1. params.require(:booking) returns a Hash-like params for #booking
2. params.class returns ActionController::Parameters
As the params seems to behave correctly, IMO the problem hides somewhere in the form:
<%= form_for #booking do |f| %>
<%= f.hidden_field :flight_id, value: params[:flight_id] %>
<%= render 'flights/flight_info' %>
<div class="field">
<b><%= f.label :num_tickets, "Tickets" %></b>
<%= f.select(:num_tickets, #num_tickets) %>
</div><br>
<h4>Passenger info:</h4>
<%= f.fields_for #booking.build_passenger do |pass| %>
<div class="field">
<%= pass.label :name %>
<%= pass.text_field :name %>
</div>
<div class="field">
<%= pass.label :email %>
<%= pass.email_field :email %>
</div>
<% end %>
<%= f.submit 'Book Flight!' %>
<% end %>
Booking model:
class Booking < ActiveRecord::Base
belongs_to :flight
belongs_to :passenger
accepts_nested_attributes_for :passenger
end
Question: Where and how do I have to edit my code for the app to start creating #booking instances + #booking.build_passenger()
Your booking_params needs to be something like:
def booking_params
params.require(:booking).permit(:flight_id, :num_tickets, passenger_attributes: [:id, :name, :email])
end

My forum is not updating the table?

I am trying to update my table by using the fourm :-
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for Message.new do |f| %>
<%= f.label :To %>
<%= f.email_field :to, class: 'form-control' %>
<%= f.label :Subject %>
<%= f.text_field :subject, class: 'form-control' %>
<%= f.label :Content %>
<%= f.text_area :content, class: 'form-control' %>
<%= f.submit "Log in", class: "btn btn-primary" %>
<% end %>
</div>
</div>
and in my controller I have done :-
def create
#message = Message.new(user_params)
redirect_to root_url
end
def user_params
params.require(:message).permit(:to, :subject, :content)
end
But when i check my Table, there is no update .
Where am i going wrong ?
My table have 2 more extra attributes , but i am not filling them up with the forum .
.new just builds the new object, you need to actually save it to persist it to the database.
def create
#message = Message.new(user_params)
#message.save!
redirect_to root_url
end

Resources