Nested attribute values set during build not being saved - ruby-on-rails

I am trying to build some nested objects with specific attribute values. A listing has_many orders, and an order has_many order_events.
Ideally, when a new listing is created and saved, the associated order (with the seller_id set) and the order_event (with the state set) should be created and saved as well.
I am running into two problems:
The order is saved, but the seller_id is not.
The order_event is not saved at all.
In the controller, I have:
def new
#listing = Listing.new
#order = #listing.orders.build(seller_id: current_user.id)
#order_event = #listing.orders.first.order_events.build(state: 'confirmed')
end
def create
#listing = Listing.new(listing_params)
respond_to do |format|
if #listing.save
format.html { redirect_to manage_path, notice: 'Listing was successfully created.' }
format.json { render :show, status: :created, location: #listing }
else
format.html { render :new }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
def listing_params
params.require(:listing).permit(:title, :address, :size, :min_lease, :price, :description, :state, space_ids: [], amenity_ids: [], images_files: [], images_attributes: [:id, :_destroy], orders_attributes: [:id, :_destroy, :start, :end, :seller_id, order_events_attributes: [:id, :_destroy, :state]])
end
Any ideas?

In your create action try assigning seller_id and #order_event like so.
def new
#listing = Listing.new
#order = #listing.orders.build
#order_event = #order.order_events.build
end
def create
#listing = Listing.new(listing_params)
#order = #listing.orders.first
#order.seller_id = current_user.id
#order_event = #order.order_events.build(state: 'confirmed')
respond_to do |format|
if #listing.save
format.html { redirect_to manage_path, notice: 'Listing was successfully created.' }
format.json { render :show, status: :created, location: #listing }
else
format.html { render :new }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end

Related

How can i use the param id in params_permit?

How can i put the id inside of my params?
so far i am doing like this:
def post_params
params.require(:post).permit(:name, :country, user_id:params[:user_id], live_id: live.id)
end
I want to put params[:user_id] and live.id inside of params
You can set live id from your controller actions instead of using param method. Please follow below steps. Hope it will be useful for you.
def create
live = Live.create()
# Set live id inside post_params
#post = Post.new(post_params.merge!(live_id: live.id))
# If you have current_user present you can set user_id as well using below way
# #post = Post.new(post_params.merge!(user_id: current_user.id, live_id: live.id))
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully
created.' }
format.json { render :show, status: :created, location:
#post }
else
format.html { render :new }
format.json { render json: #post.errors, status:
:unprocessable_entity }
end
end
end
def post_params
params.require(:post).permit(:name, :country, :user_id, :live_id)
end

Model validation not working in rails app

I have a validation in one of my models: (The sku_code validation.)
class Vendor < ActiveRecord::Base
has_many :purchases
validates :name, format: {with: /\A[A-Za-z0-9\S\s]+\z/, message: "Vendor name is invalid."}
validates :sku_code, format: {with: /\A[A-Z]{3}\z/, message: "must follow format ABC"}
end
Controller:
class VendorsController < ApplicationController
def index
#vendors = Vendor.all
respond_to do |format|
format.js
format.html
format.json
end
end
def new
#vendor = Vendor.new
respond_to do |format|
format.js
format.html
format.json
end
end
def create
#vendor = Vendor.new(vendor_params)
respond_to do |format|
if #vendor.save
format.html { redirect_to #vendor, notice: 'Vendor successfully created.' }
format.js {}
format.json { render json: #vendor, status: :created, location: #vendor }
else
format.html { render 'new' }
format.json { render json: #vendor.errors, status: :unprocessable_entity }
end
end
end
def update
#vendor = Vendor.find(params[:id])
respond_to do |format|
if #vendor.update(vendor_params)
format.html { redirect_to #vendor, notice: 'Vendor successfully updated.' }
format.js {}
format.json { render json: #vendor, status: :updated, location: #vendor }
else
format.html { render 'edit' }
format.json { render json: #vendor.errors, status: :unprocessable_entity }
end
end
end
def edit
#vendor = Vendor.find(params[:id])
respond_to do |format|
format.js
format.html
format.json
end
end
def destroy
#vendor = Vendor.find(params[:id])
#vendor.destroy
#flash.notice="Vendor '#{#vendor.name}' was deleted."
redirect_to action: "index"
end
def show
#vendor = Vendor.find(params[:id])
respond_to do |format|
format.js
format.html
format.json
end
end
private
def vendor_params
params.require(:vendor).permit(:name, :sku_code, :contact, :phone, :email, :address_line1, :address_line2, :address_city, :address_state, :address_zip, :address_country, :lead_time)
end
end
What I expected with this regex was that it would allow for a three capital letter string to be entered into my form but prevent anything else.
Currently it is rejecting the three capital letter string.
What have I done wrong here?

Overriding Named Route Parameters edit and create

I'm having some issues with Overriding Named Route Parameters when I edit or create a post I get an error undefined method playerId for nil:NilClass. It still re-directs to the :id instead of the :playerId params only with create and edit methods.
Below, :playerId should be 101, but the 6 is the :id, not sure why it's picking it up.
SELECT `players`.* FROM `players` WHERE `players`.`playerId` = 6 LIMIT 1 [["playerId", "6"]]
Routes
resources :players, param: :playerId
Controller
def show
#player = Player.find_by(playerId: params[:playerId])
#season = PlayerStat.where("playerId = ?", #player.playerId).joins(:matches).where('matches.gameType = ?', 0).where('matches.teamId = ?', #player.teamId).group('year(matches.matchDate) DESC')
end
def edit
end
def create
#player = Player.new(player_params)
respond_to do |format|
if #player.save
format.html { redirect_to #player, notice: 'PLayer was successfully created.' }
format.json { render :show, status: :created, location: #player }
else
format.html { render :new }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
def update
#player = Player.find params[:playerId]
respond_to do |format|
if #player.update(player_params)
format.html { redirect_to #player, notice: 'Player was successfully updated.' }
format.json { render :show, status: :ok, location: #player }
else
format.html { render :edit }
format.json { render json: #player.errors, status: :unprocessable_entity }
end
end
end
private
def set_player
#player = Player.find_by(playerId: params[:playerId])
end
def player_params
params.require(:player).permit(:playerId, :first_name, :last_name, :dob, :teamId, :jumper_no, :height, :weight, :image, team_attributes: [:teamId, :name], player_stats_attributes: [:playerId, :gameDate, :kicks, :marks])
end
undefined method playerId for nil:NilClass
The problem is params[:layerId] is nil upon a successful create or update because you aren't passing any playerId for the redirect_to. So #player is nil which resulted in that error. Changing your code to below should fix the error.
format.html { redirect_to player_path(#player.playerId), notice: 'PLayer was successfully created.' }
Same for update too.
you can define full routes like this:
get '/player/:playerId' => 'players#show'
get '/player/:playerId/edit' => 'players#edit'

How to make not only one object of class ruby?

I need to create array of Events instead of one with same params except event.id . This is code :
def create
#event = Event.new(event_params)
#event.user_id = current_user.id
respond_to do |format|
if #event.save
format.html { redirect_to #event, notice: 'Event was successfully created.' }
format.json { render :show, status: :created, location: #event }
else
format.html { render :new }
format.json { render json: #event.errors, status: :unprocessable_entity }
end
end
end
How should I do this?
UPD
Event params :
def event_params
params.require(:event).permit(:title, :description, :start_time, :end_time, :repeat)
end
def create
(1..10).each do |i|
params[:event][:user_id] = current_user.id
params[:event][:start_time] = params[:event][:start_time] + 24.hours if i > 1
params[:event][:end_time] = params[:event][:end_time] + 24.hours if i > 1
#event = Event.new(event_params)
#event.save
end
redirect_to events_path
end

belongs_to association not populating user_id

I had two models and wanted to add a belongs_to association. A user has_many Places. To do this I did the following:
1) Created a migration using rails g migration AddUserToPlace user:references
This created a user_id column in my places table with the following migration:
add_reference :places, :user, index: true
However when I create new places the user_id column remains blank.
What am I missing?
EDIT:
create action
def create
#place = Place.new(place_params)
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end
The user_id is not filled by default. When create new Places make sure to include the user_id in the parameters for example;
#place = Place.new();
#place.create(name: "jahn", user_id: #current_user.id)
Also try to enforce the presence of user_id in the PlaceModel
validates :user_id, presence: true
you should have something like this;
def person_params
params.require(:place).permit(:user_id, :..., :....)
end
`User_id` should be passed from the form. Otherwise for example you could do this;
def create
#place = Place.new(place_params)
#place.user_id = current_user.id
respond_to do |format|
if #place.save
format.html { redirect_to #place, notice: 'Place was successfully created.' }
format.json { render action: 'show', status: :created, location: #place }
else
format.html { render action: 'new' }
format.json { render json: #place.errors, status: :unprocessable_entity }
end
end
end

Resources