associations - one to many

I’ve got two tables in my Postgres database: categories and products.

I have a one to many relationship defined, one category can have many products.

I then created a reference and migrated the tables.

AddCategoryRefToProducts category:references

I have this in my models.

#product.rb
belongs_to :
category
#category.rb
has_many :products

I’ve fixed the _form to include the category id. But when I edit or update the form, the category id is not written to the product table.

I think I’m missing a step somewhere, not sure where.

Any suggestions?

Thanks,

Joe

You need to show the code for your edit

Ok, here is my edit products page…

<% if user_signed_in? %>

Editing Product

<%= render ‘form’ %>

<%= link_to ‘Show’, @product %> |

<%= link_to ‘Back’, products_path %>

<% else %>

You must be signed in as administrator to edit the products.

<% end %>

``

here is my _form

<%= simple_form_for(@product) do |f| %>

<%= f.error_notification %>

<%= f.label :category %><br/>



<%= f.collection_select :category, Category.all, :id, :name %>
<%= f.input :title %>

<%= f.input :template %>

<%= f.input :price %>

<%= f.input :msrp %>

<%= f.input :enddate %>

<%= f.input :draft %>
<%= f.button :submit %>

<% end %>

``

Ok, here is my edit products page...

And, more importantly, the update method in the controller, which is probably what Emmanuel meant as that is where you should be saving the data after all. Also copy/paste here what you see in the log when you click the submit button. Look first to check that everything you expect is there.

Colin

Need the code in the controller edit action

Pardon me its the update action code

class ProductsController < ApplicationController

before_action :set_product, only: [:show, :edit, :update, :destroy]

GET /products

GET /products.json

def index

@search = Product.search(params[:search])

#ransack

@search = Product.search(params[:q])

@products = @search.result.paginate(page: params[:page] , per_page: 10)

  

# @products = Product.all



# @products = @search.all



#paginate

#@product = Product.paginate(:page => params[:page], per_page: 10)

#Product.paginate(:page => params[:page], per_page: 10)

end

GET /products/1

GET /products/1.json

def show

end

GET /products/new

def new

@product = Product.new

end

GET /products/1/edit

def edit

end

POST /products

POST /products.json

def create

@product = Product.new(product_params)

respond_to do |format|

  if @product.save

    format.html { redirect_to @product, notice: 'Product was successfully created.' }

    format.json { render :show, status: :created, location: @product }

  else

    format.html { render :new }

    format.json { render json: @product.errors, status: :unprocessable_entity }

  end

end

end

PATCH/PUT /products/1

PATCH/PUT /products/1.json

def update

respond_to do |format|

  if @product.update(product_params)

    format.html { redirect_to @product, notice: 'Product was successfully updated.' }

    format.json { render :show, status: :ok, location: @product }

  else

    format.html { render :edit }

    format.json { render json: @product.errors, status: :unprocessable_entity }

  end

end

end

DELETE /products/1

DELETE /products/1.json

def destroy

@product.destroy

respond_to do |format|

  format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }

  format.json { head :no_content }

end

end

private

# Use callbacks to share common setup or constraints between actions.

def set_product

  @product = Product.find(params[:id])

end

# Never trust parameters from the scary internet, only allow the white list through.

def product_params

  # params.fetch(:product, {})

  

    params.require(:product).permit(:title, :template, :price, :msrp, :enddate)

    

end

end

``

Ok, that’s my product controller…

The problem is that you have not passed in the category id so it wont get saved. I suggest you:

  1. add category_id to your list of permitted product params
  2. introduce validations in the product model to guard against missing values

change to this also…observe the category_id attribute. I hope you have it in your product model

<%= simple_form_for(@product) do |f| %>

<%= f.error_notification %>

<%= f.label :category %><br/>

<%= f.collection_select :category_id, Category.all, :id, :name %>
<%= f.input :title %>

<%= f.input :template %>

<%= f.input :price %>

<%= f.input :msrp %>

<%= f.input :enddate %>

<%= f.input :draft %>
<%= f.button :submit %>

<% end %>

Still unsure of what to do… this is my migration to add category {id} to my products table

class AddCategoryRefToProducts < ActiveRecord::Migration

def change

add_reference :products, :category, index: true, foreign_key: true

end

end

``

Your line: params.require(:product).permit(:title, :template, :price, :msrp, :enddate)

needs to be:

Still unsure of what to do… this is my migration to add category {id} to my products table

class AddCategoryRefToProducts < ActiveRecord::Migration

def change

add_reference :products, :category, index: true, foreign_key: true

end

end

``

change to this also…observe the category_id attribute. I hope you have it in your product model

<%= simple_form_for(@product) do |f| %>

<%= f.error_notification %>

<%= f.label :category %><br/>
<%= f.collection_select :category_id, Category.all, :id, :name %>
<%= f.input :title %>
<%= f.input :template %>
<%= f.input :price %>
<%= f.input :msrp %>
<%= f.input :enddate %>
<%= f.input :draft %>
<%= f.button :submit %>

<% end %>

The problem is that you have not passed in the category id so it wont get saved. I suggest you:

  1. add category_id to your list of permitted product params
  2. introduce validations in the product model to guard against missing values

class ProductsController < ApplicationController

before_action :set_product, only: [:show, :edit, :update, :destroy]

GET /products

GET /products.json

def index

@search = Product.search(params[:search])

#ransack
@search = Product.search(params[:q])
@products = @search.result.paginate(page: params[:page] , per_page: 10)
# @products = Product.all
# @products = @search.all
#paginate
#@product = Product.paginate(:page => params[:page], per_page: 10)
#Product.paginate(:page => params[:page], per_page: 10)

end

GET /products/1

GET /products/1.json

def show

end

GET /products/new

def new

@product = Product.new

end

GET /products/1/edit

def edit

end

POST /products

POST /products.json

def create

@product = Product.new(product_params)
respond_to do |format|
  if @product.save
    format.html { redirect_to @product, notice: 'Product was successfully created.' }
    format.json { render :show, status: :created, location: @product }
  else
    format.html { render :new }
    format.json { render json: @product.errors, status: :unprocessable_entity }
  end
end

end

PATCH/PUT /products/1

PATCH/PUT /products/1.json

def update

respond_to do |format|
  if @product.update(product_params)
    format.html { redirect_to @product, notice: 'Product was successfully updated.' }
    format.json { render :show, status: :ok, location: @product }
  else
    format.html { render :edit }
    format.json { render json: @product.errors, status: :unprocessable_entity }
  end
end

end

DELETE /products/1

DELETE /products/1.json

def destroy

@product.destroy
respond_to do |format|
  format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
  format.json { head :no_content }
end

end

private

# Use callbacks to share common setup or constraints between actions.
def set_product
  @product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
  # params.fetch(:product, {})
    params.require(:product).permit(:title, :template, :price, :msrp, :enddate)
end

end

``

Ok, that’s my product controller…

Pardon me its the update action code

Need the code in the controller edit action

Ok, here is my edit products page…

<% if user_signed_in? %>

Editing Product

<%= render ‘form’ %>

<%= link_to ‘Show’, @product %> |

<%= link_to ‘Back’, products_path %>

<% else %>

You must be signed in as administrator to edit the products.

<% end %>

``

here is my _form

<%= simple_form_for(@product) do |f| %>

<%= f.error_notification %>

<%= f.label :category %><br/>
<%= f.collection_select :category, Category.all, :id, :name %>
<%= f.input :title %>
<%= f.input :template %>
<%= f.input :price %>
<%= f.input :msrp %>
<%= f.input :enddate %>
<%= f.input :draft %>
<%= f.button :submit %>

<% end %>

``

You need to show the code for your edit

I’ve got two tables in my Postgres database: categories and products.

I have a one to many relationship defined, one category can have many products.

I then created a reference and migrated the tables.

AddCategoryRefToProducts category:references

I have this in my models.

#product.rb
belongs_to :
category
#category.rb
has_many :products

I’ve fixed the _form to include the category id. But when I edit or update the form, the category id is not written to the product table.

I think I’m missing a step somewhere, not sure where.

Any suggestions?

Thanks,

Joe

You received this message because you are subscribed to the Google Groups “Ruby on Rails: Talk” group.

To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.

To post to this group, send email to rubyonra...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/8c62b187-a01f-4da3-8051-8772215ebb3d%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “Ruby on Rails: Talk” group.

To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.

To post to this group, send email to rubyonra...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/6779741f-a256-422b-8aee-ace7a38cfc91%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “Ruby on Rails: Talk” group.

To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.

To post to this group, send email to rubyonra...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/b4d9af8e-7e31-4d0a-96ef-1ae29d70e34b%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

params.require(:product).permit(:title, :template, :price, :msrp, :enddate, :category_id)

Thanks, got it.