Ahamadi
Ahamadi

Reputation: 165

Rails undefined method `email' in method update

I have model Produit that i want to update in controller ProduitsController. When i try to update i get the following error : -NoMethodError in ProduitsController#update -undefined method `email' for #

I don't have attribute email for this model (ProduitsController) and i don't know why the update methode call method email??? Is some one can please help me or give me any information?

----------here the line the error in file produits_controllers.rb-----------------------

         ##   require 'debugger'; debugger
            respond_to do |format|
    error linge ==>if @produit.update(produit_params)
                format.html { redirect_to @produit, notice: 'produit was successfully updated.' }
                format.json { render :show, status: :ok, location: @produit }
              else 
----------------------------------------------------------------------------------------

controllers/produits_controllers.rb

  class ProduitsController < ApplicationController
          before_action :set_produit, only: [:show, :edit, :update, :destroy]

      # GET /totos
      # GET /totos.json
      def index
        @produits = Produit.all
      end

      # GET /totos/1
      # GET /totos/1.json
      def show
      end

      # GET /totos/new
      def new
        @produit = Produit.new
        @etatproduits = Etatproduit.all
        @magasins = Magasin.all
      end

      # GET /totos/1/edit
      def edit
        @etatproduits = Etatproduit.all
        @magasins = Magasin.all
      end

      # POST /totos
      # POST /totos.json
      def create
         @produit = Produit.new(produit_params)

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

      # PATCH/PUT /totos/1
      # PATCH/PUT /totos/1.json
      def update
     ##   require 'debugger'; debugger
        respond_to do |format|
          if @produit.update(produit_params)
            format.html { redirect_to @produit, notice: 'produit was successfully updated.' }
            format.json { render :show, status: :ok, location: @produit }
          else
            format.html { render :edit }
            format.json { render json: @produit.errors, status: :unprocessable_entity }
          end
        end
      end

      # DELETE /totos/1
      # DELETE /totos/1.json
      def destroy
        @produit.destroy
        respond_to do |format|
         format.html { redirect_to produits_url, notice: 'produit was successfully destroyed.' }
          format.json { head :no_content }
        end
      end

      private
        # Use callbacks to share common setup or constraints between actions.
        def set_produit
          @produit = Produit.find(params[:id])
        end

        # Never trust parameters from the scary internet, only allow the white list through.
        def produit_params
           params.require(:produit).permit(:nom, :etatproduit_id, :last_change_stat, :magasin_id)
        end
    end

models/produit.rb

class Produit < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, 
         :recoverable, :rememberable, :trackable, :validatable
    belongs_to :magasin
    belongs_to :etatproduit
end

migrate/20140629085947_create_produits.rb

   class CreateProduits < ActiveRecord::Migration
      def change
        create_table :produits do |t|
          t.string :nom
          t.datetime :last_change_stat

          t.timestamps
          t.belongs_to :etatproduit
          t.belongs_to :magasin
        end

        add_index :produits, :nom
        add_index :produits, :etatproduit_id, unique: true
      end
    end

log error

Started PATCH "/produits/1" for 192.168.56.1 at 2014-07-30 01:11:18 +0000
Processing by ProduitsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"TNgQiTyu2tVnah42G9CcfupzxV9pfCGYVKo9ehWYzXA=", "produit"=>{"nom"=>"dfbdfbfdfffd", "etatproduit_id"=>"2", "magasin_id"=>"3"}, "commit"=>"Save", "id"=>"1"}
  Produit Load (0.3ms)  SELECT  `produits`.* FROM `produits`  WHERE `produits`.`id` = 1 LIMIT 1
   (0.1ms)  BEGIN
   (0.2ms)  ROLLBACK
Completed 500 Internal Server Error in 6ms

NoMethodError (undefined method `email' for #<Produit:0x000000097a6ff8>):
  app/controllers/produits_controller.rb:49:in `block in update'
  app/controllers/produits_controller.rb:48:in `update'


  Rendered /home/vagrant/.rvm/gems/ruby-2.1.1/gems/actionpack-4.1.1/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.4ms)
  Rendered /home/vagrant/.rvm/gems/ruby-2.1.1/gems/actionpack-4.1.1/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.2ms)
  Rendered /home/vagrant/.rvm/gems/ruby-2.1.1/gems/actionpack-4.1.1/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.8ms)
  Rendered /home/vagrant/.rvm/gems/ruby-2.1.1/gems/actionpack-4.1.1/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (19.6ms)

Upvotes: 0

Views: 728

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

Devise

Further to Jaugar's answer, the error is almost certainly a result of Devise

You've included Devise in your Produit model here:

#app/models/produit.rb
class Produit < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, 
         :recoverable, :rememberable, :trackable, :validatable

As mentioned, I don't know why you've got Devise in this model, but if we consider you want it in there, you have to make sure you have the accompanying attributes Devise requires (:email being one)

The immediate fix (hack) for this is to use attr_accessor to create a "virtual" attribute for email, and other Devise attributes:

#app/models/produit.rb
class Produit < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, 
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessor :email, :other, :devise, :attributes

This will not fix the problem - just mask it.

--

Solution

The solution to this is to either add the required attributes to your table, or to remove Devise from your Produit model

Considering, as Jaugar suggested, Devise is best served on the User model - I would highly recommend removing it from your Produit model. If you want to create authentication functionality for your application, you'll be best creating a User model to mount Devise onto

Upvotes: 1

Jaugar Chang
Jaugar Chang

Reputation: 3196

Why you add devise into produit model ?

Devise is usally add into User model, so user model need email attribute.

You should read more document about Devise.

If you really want add devise into produit model, you can add email attribute like this:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :timeoutable,
         :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me, :user_name
end

Upvotes: 1

Related Questions