I have a model association between two models Listing & Pricing. These are associated through Listing_Pricings model on a many to many basis.
If a listing is created the user can select through a check box field one of three pricing options which I intend to have saved in a seperate model Listing_Pricings. When a user selects the pricing option I can see it in the params hash but it fails to save in my database model.
Help please
My controller
class ListingsController < ApplicationController
protect_from_forgery except: [:upload_photo]
before_action :authenticate_user!, except: [:show]
before_action :set_listing, except: [:new, :create]
before_action :set_step, only: [:update, :edit]
before_action :is_authorised, only: [:edit, :update, :upload_photo, :delete_photo]
before_action :set_category, only: [:new, :edit, :show]
def new
@listing = current_user.listings.new
@listing.listing_pricings
@urgencies = Urgency.all
end
def create
@listing = current_user.listings.new listing_params
@listing.listing_pricings.first.listing_id = current_listing.id
if @listing.save
redirect_to edit_listing_path(@listing), notice: "Save..."
else
redirect_to request.referrer, flash: { error: @listing.errors.full_messages}
end
end
def edit
@urgencies = Urgency.all
@listing = Listing.find(params[:id])
@listing_category = @listing.category
@category_pricings = @listing_category.pricings.all
@listing_price = @listing.listing_pricings
end
def update
@listing = Listing.find(params[:id])
@listing_category = @listing.category
#@category_pricings = @listing_category.pricings.all
#@category = Category.find(params[:id])
@category_pricings = @listing_category.pricings.paginate(page: params[:page], per_page: 5)
@listing_pricing = @listing.listing_pricings
#@listing_price = @listing_pricing.first.pricing
@listing_price = @listing.listing_pricings.build
@urgencies = Urgency.all
if @step == 2 && @listing.listing_pricings.each do |pricing|
if @listing.has_single_pricing && !pricing.bronze?
next;
else
if pricing[:listing_id].blank?
#|| pricing[:description].blank? || pricing[:complete_by_date].blank? || pricing[:price].blank?
return redirect_to request.referrer, flash: {error: "Invalid Pricing"}
end
end
end
end
if @step == 3 && listing_params[:description].blank?
return redirect_to request.referrer, flash: {error: "Description cannot be blank"}
end
if @step == 4 && @listing.photos.blank?
return redirect_to request.referrer, flash: {error: "You don't have any photos"}
end
if @step == 5
@listing_category_pricings.each do |pricing|
if @listing.has_single_pricing || !pricing.bronze? || !pricing.silver? || !pricing.gold? || !pricing.platinum?
next;
else
if pricing[:overview].blank? || pricing[:description].blank? || pricing[:complete_by_date].blank? || pricing[:price].blank?
return redirect_to edit_listing_path(@listing, step: 2), flash: {error: "Invalid pricing"}
end
end
end
if @listing.description.blank?
return redirect_to edit_listing_path(@listing, step: 3), flash: {error: "Description cannot be blank"}
elsif @listing.photos.blank?
return redirect_to edit_listing_path(@listing, step: 4), flash: {error: "You don't have any photos"}
end
end
if @listing.update(listing_params)
flash[:notice] = "Saved..."
else
return redirect_to request.referrer, flash: {error: @listing.errors.full_messages}
end
if @step < 5
redirect_to edit_listing_path(@listing, step: @step + 1)
else
redirect_to users_dashboard_path
end
end
def show
@listing = Listing.find(params[:id])
@listing_category = @listing.category
@listing_category_pricings = @listing_category.pricings.all
@urgencies = Urgency.all
end
def upload_photo
@listing.photos.attach(params[:file])
render json: { success: true}
end
def delete_photo
@image = ActiveStorage::Attachment.find(params[:photo_id])
@image.purge
redirect_to edit_listing_path(@listing, step: 4)
end
def set_pricing_id
Listing.update_all({pricing_id: true}, {id: params[:listing_id]} )
end
private
def set_step
@step = params[:step].to_i > 0 ? params[:step].to_i : 1
if @step > 5
@step = 5
end
end
def set_category
@categories = Category.all
end
def set_listing
@listing = Listing.find(params[:id])
end
def is_authorised
redirect_to root_path, alert: "You do not have permission" unless current_user.id == @listing.user_id
end
def listing_params
params.require(:listing).permit(:title, :video, :description, :active, :category_id, :budget, :urgency_id, :has_single_pricing,:pricing_id)
end
def category_params
params.require(:category).permit(:name)
end
end
Listing.rb
class Listing < ApplicationRecord
belongs_to :user
belongs_to :category
belongs_to :urgency
has_many :listing_pricings, dependent: :destroy
has_many :pricings, through: :listing_pricings
has_many_attached :photos
has_rich_text :description
validates :title, presence: { message: 'cannot be blank' }
#has_many :pricings
#accepts_nested_attributes_for :pricings
#has_many :listing_categories
end
Pricings.rb
class Pricing < ApplicationRecord
belongs_to :category, optional: false
has_many :listing_pricings
has_many :listings, through: :listing_pricings
enum pricing_type: [:bronze, :silver, :gold, :platinum]
end
ListingPricing.rb
class ListingPricing < ApplicationRecord
belongs_to :listing, optional: true, dependent: :destroy
belongs_to :pricing, optional: true, dependent: :destroy
end
My View
<div class="step-content <%= 'is-active' if @step == 2 %>">
<div class="field">
<div class="control">
<div class="tile is-ancestor">
<% @category_pricings.each do |cp| %>
<div class="tile is-parent">
<article class="tile is-child box">
<div class="subtitle"><%= "#{cp.overview}" %></div>
<div class="content"><%= "Deposit payable: £#{cp.price}" %></div>
<div class="content"><%= "Time to complete: #{pluralize(cp.complete_by_date, 'Day')}" %></div>
<tr valign="bottom"><div class="content"><%= "#{cp.description}" %></div></tr>
<tr valign="bottom"><div class="content"><%= "#{cp.id}" %></div></tr>
<%= f.fields_for :listing_pricings do |lp| %>
<%= hidden_field_tag "pricing_id[]", cp.id %>
<div class="form-group">
<%= lp.check_box_tag :pricing_id, cp.id %>
</div>
<% end %>
</article>
</div>
<% end %>
</div>
</div>
</div>
</div>
My error trace says PG::NotNullViolation: ERROR: null value in column "pricing_id" violates not-null constraint DETAIL: Failing row contains (16, 2, null, 2019-12-13 17:51:50.722906, 2019-12-13 17:51:50.722906).
Any thoughts guys ?
Parameters:
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"tOnX6Q5YjHgXn3Xk5Wh2NioPfLrziiPVwyHkLF8BBFOjuWHdM1w8A7AdGpHdFGR3n+zlFsN2B/3IOMenXU1daA==",
"step"=>"2",
"listing"=>{"title"=>"Please clean my home", "category_id"=>"3", "urgency_id"=>"10", "has_single_pricing"=>"0", "description"=>"<div>This is my second listing </div>", "video"=>""},
"pricing_id"=>"1",
"commit"=>"Save & Continue",
"id"=>"2"}