0

There is a model. I want to have multiple with_options statements and do some actions depending on some inner flags before save. Here is a class, for example:

class User < ActiveRecord::Base

  with_options if: :with_password do |record|
    # some validation and before_filter stuff
  end

  with_options if: :resetting_password do |record|
    # some other validation and before_filter stuff
  end

  def save_with_password
    self.with_password = true
    save
  end

  def reset_password
    self.resetting_password = true
    assign_attributes(password: DEFAULT_PASSWORD)
    save
  end

  private

  attr_accessor :with_password
  attr_accessor :resetting_password

end

This code is not working because the first with_options is overridden by the second with_options and if self.with_password == true then the first with_options is not being executed (as well as the second one).

So how can I make it work?

--- UPDATE

Here is an example of a test which passes if with_options if: :resetting_password is below with_options if: :with_password and fails if vice versa.

describe '#reset_password' do
  let(:instance) { stub_model(described_class, name: 'admin') }
  subject { instance.reset_password }

  it 'sets password to a default one' do
    subject
    expect(instance.has_password?("default")).to eq true
  end

end

Gemfile.lock:

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (4.1.1)
      actionpack (= 4.1.1)
      actionview (= 4.1.1)
      mail (~> 2.5.4)
    actionpack (4.1.1)
      actionview (= 4.1.1)
      activesupport (= 4.1.1)
      rack (~> 1.5.2)
      rack-test (~> 0.6.2)
    actionview (4.1.1)
      activesupport (= 4.1.1)
      builder (~> 3.1)
      erubis (~> 2.7.0)
    activemodel (4.1.1)
      activesupport (= 4.1.1)
      builder (~> 3.1)
    activerecord (4.1.1)
      activemodel (= 4.1.1)
      activesupport (= 4.1.1)
      arel (~> 5.0.0)
    activesupport (4.1.1)
      i18n (~> 0.6, >= 0.6.9)
      json (~> 1.7, >= 1.7.7)
      minitest (~> 5.1)
      thread_safe (~> 0.1)
      tzinfo (~> 1.1)
    arel (5.0.1.20140414130214)
    builder (3.2.2)
    chunky_png (1.3.1)
    compass (0.12.7)
      chunky_png (~> 1.2)
      fssm (>= 0.2.7)
      sass (~> 3.2.19)
    compass-rails (2.0.0)
      compass (>= 0.12.2)
    diff-lcs (1.2.5)
    erubis (2.7.0)
    execjs (2.2.0)
    fssm (0.2.10)
    haml (4.0.5)
      tilt
    haml-rails (0.5.3)
      actionpack (>= 4.0.1)
      activesupport (>= 4.0.1)
      haml (>= 3.1, < 5.0)
      railties (>= 4.0.1)
    hike (1.2.3)
    i18n (0.6.9)
    jbuilder (2.1.1)
      activesupport (>= 3.0.0, < 5)
      multi_json (~> 1.2)
    jquery-rails (3.1.1)
      railties (>= 3.0, < 5.0)
      thor (>= 0.14, < 2.0)
    json (1.8.1)
    mail (2.5.4)
      mime-types (~> 1.16)
      treetop (~> 1.4.8)
    mime-types (1.25.1)
    mini_magick (3.8.0)
      subexec (~> 0.2.1)
    mini_portile (0.6.0)
    minitest (5.3.5)
    multi_json (1.10.1)
    nokogiri (1.6.3.1)
      mini_portile (= 0.6.0)
    nokogiri (1.6.3.1-x86-mingw32)
      mini_portile (= 0.6.0)
    polyglot (0.3.5)
    rack (1.5.2)
    rack-test (0.6.2)
      rack (>= 1.0)
    rails (4.1.1)
      actionmailer (= 4.1.1)
      actionpack (= 4.1.1)
      actionview (= 4.1.1)
      activemodel (= 4.1.1)
      activerecord (= 4.1.1)
      activesupport (= 4.1.1)
      bundler (>= 1.3.0, < 2.0)
      railties (= 4.1.1)
      sprockets-rails (~> 2.0)
    railties (4.1.1)
      actionpack (= 4.1.1)
      activesupport (= 4.1.1)
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    rake (10.3.2)
    rdoc (4.1.1)
      json (~> 1.4)
    rspec (3.0.0)
      rspec-core (~> 3.0.0)
      rspec-expectations (~> 3.0.0)
      rspec-mocks (~> 3.0.0)
    rspec-activemodel-mocks (1.0.1)
      activemodel (>= 3.0)
      activesupport (>= 3.0)
      rspec-mocks (>= 2.99, < 4.0)
    rspec-core (3.0.2)
      rspec-support (~> 3.0.0)
    rspec-expectations (3.0.2)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.0.0)
    rspec-html-matchers (0.6.1)
      nokogiri (~> 1)
      rspec (~> 3)
    rspec-mocks (3.0.2)
      rspec-support (~> 3.0.0)
    rspec-rails (3.0.1)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      railties (>= 3.0)
      rspec-core (~> 3.0.0)
      rspec-expectations (~> 3.0.0)
      rspec-mocks (~> 3.0.0)
      rspec-support (~> 3.0.0)
    rspec-support (3.0.2)
    sass (3.2.19)
    sass-rails (4.0.3)
      railties (>= 4.0.0, < 5.0)
      sass (~> 3.2.0)
      sprockets (~> 2.8, <= 2.11.0)
      sprockets-rails (~> 2.0)
    sdoc (0.4.0)
      json (~> 1.8)
      rdoc (~> 4.0, < 5.0)
    sprockets (2.11.0)
      hike (~> 1.2)
      multi_json (~> 1.0)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    sprockets-rails (2.1.3)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      sprockets (~> 2.8)
    sqlite3 (1.3.9)
    sqlite3 (1.3.9-x86-mingw32)
    subexec (0.2.3)
    thor (0.19.1)
    thread_safe (0.3.4)
    tilt (1.4.1)
    treetop (1.4.15)
      polyglot
      polyglot (>= 0.3.1)
    tzinfo (1.2.1)
      thread_safe (~> 0.1)
    tzinfo-data (1.2014.5)
      tzinfo (>= 1.0.0)
    uglifier (2.5.1)
      execjs (>= 0.3.0)
      json (>= 1.8.0)

PLATFORMS
  ruby
  x86-mingw32

DEPENDENCIES
  compass-rails
  haml-rails (~> 0.5.3)
  jbuilder (~> 2.0)
  jquery-rails
  mini_magick
  rails (= 4.1.1)
  rspec-activemodel-mocks
  rspec-html-matchers
  rspec-rails (~> 3.0.0)
  sass-rails (~> 4.0.3)
  sdoc (~> 0.4.0)
  sqlite3
  tzinfo-data
  uglifier (>= 1.3.0)
6
  • Please add what is within with_options - with_options do not override each other, so most likely you are misusing it (which is likely as you named yielded value record). How did you check if validations are being run or not, in console or through the server? Commented Nov 7, 2014 at 23:00
  • I have updated my question. When call save_with_password the first with_options is not executed - because there is a method which encrypts the password and set it to a attribute, model even cannot be stored due to constraints. reset_password works. When I remove the second with_options then save_with_password works. When I change order of with_optionss then save_with_password works but reset_password doesn't work. Commented Nov 7, 2014 at 23:09
  • could you show how you use record object? Commented Nov 7, 2014 at 23:11
  • hmmm.. seems that this problem is related only to rspecs. Testing these methods from console - OK, from rspec - fail. Commented Nov 7, 2014 at 23:18
  • Tried with FactoryGirl - the same result Commented Nov 7, 2014 at 23:53

1 Answer 1

2

Solved. Rewrote with_options like this:

class User < ActiveRecord::Base

  with_options if: :with_password do |record|
    # some validation and before_filter stuff
  end

  with_options if: :resetting_password do |record|
    # some other validation and before_filter stuff
  end

  with_options if: ->{ with_password || resetting_password } do |record|
    # some common stuff
  end

end
Sign up to request clarification or add additional context in comments.

1 Comment

ugh, notice that the last option, the one you want, has no symbols... meaning that I updated existing code using :with_password but it should be with_password hope I save someone else. subtle but annoying!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.