Search code examples
ruby-on-railsruby-on-rails-3protected

Assignment of protected attribute for email confirmation rails


There are several questions that address very similar issues, but either I am misunderstanding the solutions or some nuance in the questioner's situation.

The attribute confirmed is protected, and thus I cannot mass assign it. After researching it, it seems like the following solution should work. I am able to view both the token (also protected) and the confirmed in the flash, but I am not able to set `confirmed' below that. What am I doing wrong?

  if [email protected] && params[:token] == @user.token
    flash[:success] = @user.token, @user.confirmed
    @user.confirmed = true
    @user.save
  end

Thanks for reading!


Solution

  • I have replicated your scenario in one of my test apps and I am able to set published (in your case confirmed) to true.

    Migration

    def up
        create_table :posts do |t|
          t.string :title
          t.boolean :published, :default => false
          t.string :token
          t.timestamps
    end
    

    Model

     class Post < ActiveRecord::Base
      attr_protected :published
    
      before_create :generate_token
    
      def generate_token
        self.token = Time.now().to_i
      end
    
    end
    

    Controller

    class PostsController < ApplicationController
    
      def publish
        @post = Post.find_by_token(params[:token])
        if [email protected] && params[:token] == @post.token # The second condition is not necessary in this case.
          @post.published = true
          @post.save
        end
      end
    end
    

    Creating the DB record form console

    1.9.3-p0-perf :001 > p = Post.new({:title => "Protests against Violence"})
     => #<Post id: nil, title: "Protests against Violence", published: false, token: nil, created_at: nil, updated_at: nil> 
    1.9.3-p0-perf :002 > p.save
       (0.2ms)  BEGIN
      SQL (7.3ms)  INSERT INTO "posts" ("created_at", "published", "title", "token", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["created_at", Thu, 14 Feb 2013 07:41:58 UTC +00:00], ["published", false], ["title", "Protests against Violence"], ["token", 1360827718], ["updated_at", Thu, 14 Feb 2013 07:41:58 UTC +00:00]]
       (7.5ms)  COMMIT
     => true 
    1.9.3-p0-perf :003 > p.reload
      Post Load (1.2ms)  SELECT "posts".* FROM "posts" WHERE "posts"."id" = $1 LIMIT 1  [["id", 2]]
     => #<Post id: 2, title: "Protests against Violence", published: false, token: "1360827718", created_at: "2013-02-14 07:41:58", updated_at: "2013-02-14 07:41:58"> 
    

    After hitting the /publish/1360827718 - here is the output from the console

    #<Post id: 2, title: "Protests against Violence", published: true, token: "1360827718", created_at: "2013-02-14 07:41:58", updated_at: "2013-02-14 07:45:33"> 
    

    I am running this code with postgresql, rails 3.2.11 and ruby 1.9.3 and the publish action in the controller sets the published=true

    Sometimes comparing the code that works with the one that doesn't helps identify the problem and that's the intention behind this answer.

    Hope this helps you to identify the problem.