associations - one to many

36 views
Skip to first unread message

Joe Guerra

unread,
Sep 30, 2016, 10:51:19 AM9/30/16
to Ruby on Rails: Talk

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

Emmanuel Abia

unread,
Sep 30, 2016, 10:58:34 AM9/30/16
to rubyonrails-talk@googlegroups com

You need to show the code for your edit


--
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-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@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.

Joe Guerra

unread,
Sep 30, 2016, 11:03:02 AM9/30/16
to Ruby on Rails: Talk
Ok, here is my edit products page...

<% if user_signed_in? %>  <!-- fix this change to admin user -->

<h1>Editing Product</h1>

<%= render 'form' %>

<%= link_to 'Show', @product %> |
<%= link_to 'Back', products_path %>

<% else %>


    <div class="alert alert-warning" role="alert">You must be signed in as administrator to edit the products.</div>
  
<% end %> 


here is my _form

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


 <!-- fix this -->
 <div class = "field">
    
    <%= f.label :category %><br/>
    
    <%= f.collection_select :category, Category.all, :id, :name %>
  </div>
  <!-- fix this, it should save the category to the model -->
  
  <div class="form-inputs">
    
    <%= f.input :title %>
    <%= f.input :template %>
    <%= f.input :price %>
    <%= f.input :msrp %>
    <%= f.input :enddate %>
    <%= f.input :draft %>
  
 
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>







On Friday, September 30, 2016 at 10:58:34 AM UTC-4, mode-x wrote:

You need to show the code for your edit

On 30 Sep 2016 3:51 p.m., "Joe Guerra" <jgu...@jginfosys.com> wrote:

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.

Colin Law

unread,
Sep 30, 2016, 11:18:53 AM9/30/16
to Ruby on Rails: Talk
On 30 September 2016 at 16:03, Joe Guerra <jgu...@jginfosys.com> wrote:
> 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
> https://groups.google.com/d/msgid/rubyonrails-talk/6779741f-a256-422b-8aee-ace7a38cfc91%40googlegroups.com.

Emmanuel Abia

unread,
Sep 30, 2016, 11:31:47 AM9/30/16
to rubyonrails-talk@googlegroups com

Need the code in the controller edit action


To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@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.

Emmanuel Abia

unread,
Sep 30, 2016, 11:38:34 AM9/30/16
to rubyonrails-talk@googlegroups com

Pardon me its the update action code

Joe Guerra

unread,
Sep 30, 2016, 11:43:50 AM9/30/16
to Ruby on Rails: Talk

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...

Emmanuel Abia

unread,
Sep 30, 2016, 3:23:38 PM9/30/16
to rubyonra...@googlegroups.com
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





To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@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.

Emmanuel Abia

unread,
Sep 30, 2016, 3:33:04 PM9/30/16
to rubyonra...@googlegroups.com
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 %>
  <div class = "field">
    <%= f.label :category %><br/>
    <%= f.collection_select :category_id, Category.all, :id, :name %>
  </div> 
  <div class="form-inputs">
    <%= f.input :title %>
    <%= f.input :template %>
    <%= f.input :price %>
    <%= f.input :msrp %>
    <%= f.input :enddate %>
    <%= f.input :draft %>
  </div>
  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Joe Guerra

unread,
Oct 4, 2016, 3:15:26 PM10/4/16
to Ruby on Rails: Talk
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

Chris Lerum

unread,
Oct 18, 2016, 8:48:51 AM10/18/16
to Ruby on Rails: Talk
Your line:
params.require(:product).permit(:title, :template, :price, :msrp, :enddate)
needs to be:
params.require(:product).permit(:title, :template, :price, :msrp, :enddate, :category_id)

Joe Guerra

unread,
Oct 21, 2016, 2:21:17 PM10/21/16
to Ruby on Rails: Talk

Thanks, got it. 
Reply all
Reply to author
Forward
0 new messages