I get blank message without the password reset message and link, when I request to reset my password. I am using devise
Here is my passwords controller:
class PasswordsController < Devise::PasswordsController
def create
self.resource = resource_class.send_reset_password_instructions(resource_params)
respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
end
end
registrations controller:
class RegistrationsController < Devise::RegistrationsController
def create
if verify_recaptcha
super
else
build_resource
clean_up_passwords(resource)
render :new
end
end
end
routes.rb:
devise_for :users, controllers: { passwords: 'passwords' }
devise_for :users, :path_names=> {:sign_in=> "login", :sign_out=> "logout"},
:controllers => { :registrations => 'registrations' }
Related
I know there are a couple questions around this topic, one is almost identical since we followed the same tutorial, but none of the answers are working for me. I followed emerson lackey's tutorial on attaching multiple images with paperclip (http://emersonlackey.com/screencasts/rails-3-with-paperclip.mov) and am having the error Can't mass-assign protected attributes: assets_attributes. One note as you look at the code, I had been running with only image per post so there is terminology for images vs. assets that will be deleted but need right now for the rest of the site to work.
I have created an Asset ID and added it to the asset model. Also note that I have Pins instead of Posts.
In the pin.rb Model:
class Pin < ActiveRecord::Base
attr_accessible :description, :image, :image_remote_url, :Designer, :price, :retail_value, :condition, :lender_notes, :size, :material, :color, :classification, :item_category, :asset_attributes
validates :user_id, presence: true
validates :description, presence: true
validates :Designer, presence: true
validates :size, presence: true
validates :color, presence: true
validates :material, presence: true
validates :price, presence: true
validates :retail_value, presence: true
validates :condition, presence: true
validates :lender_notes, presence: true
validates :classification, presence: true
validates :item_category, presence: true
validates_attachment :asset, presence: true,
content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'] },
size: { less_than: 5.megabytes }
belongs_to :user
has_many :line_items
has_many :assets
accepts_nested_attributes_for :assets, :allow_destroy => true
before_destroy :ensure_not_referenced_by_any_line_item
has_attached_file :image, styles: { medium: "320x240"}
# ensure that there are no line items referencing this product
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items present')
return false
end
end
def image_remote_url=(url_value)
self.image = URI.parse(url_value) unless url_value.blank?
super
end
end
In the asset.rb model:
class Asset < ActiveRecord::Base
attr_accessible :asset
belongs_to :pin
has_attached_file :asset, :styles => { :large => "640x480", :medium => "320x240", :thumb => "100x100>" }
end
in the pins_controller.rb file:
class PinsController < ApplicationController
before_filter :authenticate_user!, except: [:index]
def index
#pins = Pin.order("created_at desc").page(params[:page]).per_page(20)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #pins }
format.js
end
end
def show
#pin = Pin.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #pin }
end
end
def new
#pin = current_user.pins.new
5.times { #pin.assets.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: #pin }
end
end
def edit
#pin = current_user.pins.find(params[:id])
5.times { #pin.assets.build }
end
def create
#pin = current_user.pins.new(params[:pin])
respond_to do |format|
if #pin.save
format.html { redirect_to #pin, notice: 'Pin was successfully created.' }
format.json { render json: #pin, status: :created, location: #pin }
else
format.html { render action: "new" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
def update
#pin = current_user.pins.find(params[:id])
respond_to do |format|
if #pin.update_attributes(params[:pin])
format.html { redirect_to #pin, notice: 'Pin was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
def destroy
#pin = current_user.pins.find(params[:id])
#pin.destroy
respond_to do |format|
format.html { redirect_to pins_url }
format.json { head :no_content }
end
end
end
In the _form.html.erb file:
<%= simple_form_for(#pin, :html => { :multipart => true}) do |f| %>
<%= f.full_error :asset_file_size, class: "alert alert-error" %>
<%= f.full_error :asset_content_type, class: "alert alert-error" %>
<%= f.fields_for :assets do |asset_fields| %>
<%= asset_fields.file_field :asset %>
<% end %>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-primary" %>
</div>
<% end %>
Thank you!!!!!
You said the error is:
Can't mass-assign protected attributes: assets_attributes
You don't have this defined in attr_accessible; you have :asset_attributes but not :assets_attributes
Try changing it to the plural version.
My models relationship like
class Cart < ActiveRecord::Base
has_many :cart_items, :inverse_of => :cart, :dependent => :destroy
accepts_nested_attributes_for :cart_items, :allow_destroy => :true, :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
validates_associated :cart_items
validates :cart_name, :presence => {:message => "Must be filled" }
end
class CartItem < ActiveRecord::Base
belongs_to :cart, :inverse_of => :cart_items
validates :cart_item_no, :presence => {:message => "Must be filled"}, :uniqueness => {:message => "Already exists" }
end
factories.rb
FactoryGirl.define do
factory :cart do
cart_name "sample"
factory :cart_with_cart_items do
after(:build) {|cart|
2.times { cart.cart_items.build(attributes_for(:cart_item)) }
}
after(:create) {|cart|
cart.cart_items.each {|cart_item| cart_item.save! }
}
end
end
factory :cart_item do
cart_item_no 1
cart
end
end
Below test case always fails
it "should not be valid with same cart_id" do
cart = FactoryGirl.build(:cart_with_cart_items)
cart.should_not be_valid
end
then I exploring in console, validation always returning true with same *cart_item_no* twice in cart_items by the example of below code.
cart = Cart.new(:cart_name => "yyy")
=> #<Cart id: nil, cart_name: "yyy">
2.times { cart.cart_items.build(:cart_item_no => 1000) }
=> 2
cart.cart_items
=> [#<CartItem id: nil, cart_item_no: 1000>, #<CartItem id: nil, cart_item_no: 1000>]
cart.valid?
=> true
cart.save!
=> true
Is this rails problem?
how to solve test case?
Uniqness validation checks against the database only. In your case, you have two cart_items that conflict with each other but not with any record in the database, so individually, both are valid, which is why your validations passes.
You could add a custom validation in your Cart class (not tested):
validates :unique_cart_items
def unique_cart_items
unless cart_items.collect(&:cart_item_no).uniq.size < cart_items.size
# set some error attribute here
end
end
This compares the number of unique cart_item_no values to the number of cart_items. If they are not the same, there's a duplicate cart_item_no.
I would like to be able to authenticate through a curl style !
So I would like to get a Token when I signed in :
curl -X POST 'http://localhost:3000/users/sign_in.json' -d 'user[email]=em...#provider.us&user[password]=pass'
But if I perform this action I only get :
{"email":"em...#provider.us","name":"Name of the user"}
How I could add some specific fields like authentication_token ?
Is what I want to do is right ? Is there any other better way to do
this ?
Thanks !
I created a Controller named SessionController
class Users::SessionsController < Devise::SessionsController
append_view_path 'app/views/devise'
def create
respond_to do |format|
format.html { super }
format.json {
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
current_user.ensure_authentication_token!
render :json => {:user => current_user.api_attributes, :auth_token => current_user.authentication_token}.to_json, :status => :ok
}
end
end
def destroy
respond_to do |format|
format.html { super }
format.json {
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
current_user.empty_authentication_token!
render :json => {}.to_json, :status => :ok
}
end
end
end
And added this to the root file :
devise_for :users, :controllers => { :sessions => "users/sessions" }
And it works :-)
I am playing with rails 3.0.6 with ruby 1.9.2,
the app is working on browser but not in testing..
1) I created a new rails application by "rails new myapp"
2) Generate a scaffold "rails generate scaffold user username:string hashed_password:string salt:string"
3) after that, i changed the users_controller a bit
# POST /users
# POST /users.xml
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
// change #user to usrs_url
format.html { redirect_to(users_url, :notice => "User #{#user.username} was successfully created.") }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
# PUT /users/1
# PUT /users/1.xml
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
// change #user to usrs_url
format.html { redirect_to(users_url, :notice => "User #{#user.username} was successfully updated.") }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
4) so i try to modify tests as well:
setup do
#input_attributes = {
:username => 'username#goodmail.com',
:password => 'secret',
:password_confirmation => 'secret'
}
#user = users(:one)
end
test "should create user" do
assert_difference('User.count') do
post :create, :user => #input_attributes
end
assert_redirected_to users_path
end
test "should update user" do
put :update, :id => #user.to_param, :user => #input_attributes
assert_redirected_to users_path
end
But the create and update tests failed
Can anyone let me know what had i done wrong?
Thanks
Loaded suite C:/Ruby192/lib/ruby/1.9.1/rake/rake_test_loader
Started
F.....F
Finished in 5.628874 seconds.
1) Failure:
test_should_create_user(UsersControllerTest) [test/functional/users_controller_test.rb:26]:
"User.count" didn't change by 1.
<3> expected but was
<2>.
2) Failure:
test_should_update_user(UsersControllerTest) [test/functional/users_controller_test.rb:45]:
Expected block to return true value.
7 tests, 9 assertions, 2 failures, 0 errors, 0 skips
require 'digest/sha2'
class User < ActiveRecord::Base
validates :username, :presence => true, :uniqueness => true
validates_format_of :username, :with => /\A^[^\r\n# ][^\r\n# ]+#[^\r\n# ]+[.][^\r\n#. ]+$\Z/i
#password is a fake field
validates :password, :confirmation => true
validate :password_must_be_present
attr_accessor :password_confirmation
attr_reader :password
def password=(password)
if password.present?
generate_salt
self.hashed_password = self.class.encrypt_password(password, salt)
end
end
class << self
def encrypt_password(password, salt)
Digest::SHA2.hexdigest(password + "shrimpy" + salt)
end
def authenticate(username, password)
if user = find_by_username(username)
if user.hashed_password == encrypt_password(password, user.salt)
user
end
end
end
end
private
def password_must_be_present
errors.add(:password, "Missing password") unless hashed_password.present?
end
def generate_salt
self.salt = self.object_id.to_s + rand.to_s
end
end
assert_redirected_to user_path is singular. You probably don't even have a singular user resource route defined. What you want there is probably assert_redirected_to users_path with a plural users.
I was following the tutorial at http://www.logansbailey.com/ and modified it to enable an unregistered person to be able to register with a username, email and password.
I already enabled a logged in user to modify his/her email and password but not the username.
What I want to add is:
1) to enable a logged in user to be able to see/reach his/her username and email,
2) to enable a user with admin_flag set (I handled this in the sql table and created the user) to be able to see/modify all user records.
I modifyed the app/cotrollers/user_controller.rb like this:
class UsersController < ApplicationController
before_filter :is_user, :only => [:index, :show, :edit, :update, :destroy]
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
end
end
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #user }
end
end
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #user }
end
end
def edit
end
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
flash[:notice] = 'Registration successful.'
format.html { redirect_to(:controller => 'home', :action => 'tutorial') }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #user.update_attributes(params[:user])
flash[:notice] = 'Your profile was successfully updated.'
format.html { redirect_to(:controller => 'home', :action => 'index') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to(users_url) }
format.xml { head :ok }
end
end
def is_user
if User.exists?(params[:id])
#user = User.find(params[:id]);
if current_user.admin_flag == true
flash[:notice] = 'Welcome Admin'
end
if !current_user || current_user.id != #user.id
flash[:notice] = 'You do not have access to that page'
redirect_to(:controller => 'home', :action => 'index')
end
else
flash[:notice] = 'You do not have access to that page'
redirect_to(:controller => 'home', :action => 'index')
end
end
end
The file app/models/user.rb is:
class User < ActiveRecord::Base
acts_as_authentic
end
And I can confirm that the admin_flag set user is get correctly since the file app/views/layouts/application.html.erb containing:
<div id="admin">
<% if current_user %>
<% if current_user.admin_flag == true %> |
<%= link_to "Users", users_path %>
<% end %>
<% end %>
</div>
correctly displays the 'Users' link when I log in as the admin.
Now the problem is that I can't get the show all users, edit other users etc.. functionality. As the admin, I can show and modify the admin user just like all the other ordinary users, meaning I can't modify the username, too.
What may be wrong here?
When you added a boolean attribute admin to user in the right way, the Rails should add question-mark method admin? in User model. It's not important but for convenience.
On every method you want to protect from unwanted actions use before_filter:
class UsersController < ApplicationController
before_filter :admin_user, :only => :destroy
before_filter :correct_user, :only => [:edit, :update]
def destroy
end
...
private
def admin_user
redirect_to(root_path) unless current_user.admin?
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user) || current_user.admin?
end
end
In views more convenient to use current_user.admin?
<div id="admin">
<% if current_user.admin? %>
<%= link_to "Users", users_path %>
<% end %>
</div>