Sunday, 15 August 2010

ruby on rails - Creating a class that has_one other class -



ruby on rails - Creating a class that has_one other class -

when run next test:

describe "ghost pages" subject { page } let(:user) { factorygirl.create(:user) } before user.save end describe "for signed-in user" before sign_in user end describe "trying view own ghost" before visit ghost_path(user.ghost) end { should have_title('ghost') } end end end

i next error, , can't identify cause:

failure/error: visit ghost_path(user.ghost)

activerecord::recordnotfound:

couldn't find ghost id=429

./app/controllers/ghosts_controller.rb:48:in `correct_ghost'

each user has_one ghost. ghost created automatically when user signs , created (self.create_ghost). perhaps ghost not beingness saved correctly somehow?

the relevant bits of code are:

class user < activerecord::base has_one :ghost, dependent: :destroy before_create :create_remember_token before_save email.downcase! self.create_ghost end validates :name, presence: true, length: { maximum: 50 } valid_email_regex = /\a[\w+\-.]+@[a-z\d\-]+(?:\.[a-z\d\-]+)*\.[a-z]+\z/i validates :email, presence: true, format: { with: valid_email_regex }, uniqueness: { case_sensitive: false } validates :password, length: { minimum: 6 } end class ghost < activerecord::base belongs_to :user validates :user_id, presence: true end class userscontroller < applicationcontroller before_action :signed_in_user, only: [:index, :show, :edit, :update, :destroy] before_action :non_signed_in_user, only: [:new, :create] before_action :correct_user, only: [:edit, :update] before_action :admin_user, only: :destroy def index @users = user.paginate(page: params[:page]) end def show @user = user.find(params[:id]) end def new @user = user.new end def create @user = user.new(user_params) if @user.save sign_in @user flash[:success] = "welcome!" redirect_to @user else render 'new' end end end class ghostscontroller < applicationcontroller before_action :signed_in_user before_action :correct_ghost, only: [:show] before_action :correct_destroyer, only: [:destroy] before_action :go_away, only: [:index, :edit, :update] def index end def edit end def update end def show @ghost = ghost.find(params[:id]) end def new @ghost = ghost.new end def create @ghost = current_user.build_ghost(ghost_params) if @ghost.save flash[:success] = "ghost created" else flash[:error] = "ghost creation failed" end end def destroy @ghost = ghost.find(params[:id]) @ghost.destroy flash[:success] = "ghost deleted, master." redirect_to current_user end private def ghost_params params.require(:ghost).permit() end def correct_ghost @ghost = ghost.find(params[:id]) redirect_to(root_url) unless (current_user.id == @ghost.user_id) end def correct_destroyer redirect_to(root_url) unless current_user.admin? end def go_away redirect_to(root_url) end end

let(:user) { factorygirl.create(:user) } before user.save end

when before block executed user returns newly created user, phone call save on it. before_save callback run twice. when run part of code see:

failed remove existing associated ghost. record failed save after foreign key set nil.

your results may differ. in case, don't want create 2 ghosts.

you alter callback avoid creating ghost when 1 exists:

before_save create_ghost unless ghost end

but may preferable utilize before_create instead, since want create ghost once.

before_create create_ghost end

ruby-on-rails rspec

No comments:

Post a Comment