Re: What is the best modelstructure and routes?

What do you need from my test.log file in order to help?

Re: What is the best modelstructure and routes?

Add the launchy gem to your development test group in the Gemfile.rb then run bundle install. You just need

gem 'launchy'

This will enable the save_and_open_page command to launch your default browser. Remember to comment out or delete the save_and_open_page declaration as you don't want loads of pages opening up every time you run your tests

You might find this cast usefull http://railscasts.com/episodes/257-requ … d-capybara

What you want and what you need are too often not the same thing!
When your head is hurting from trying to solve a problem, stop standing on it. When you are the right way up you will see the problem differently and you just might find the solution.
(Quote by me 15th July 2009)

Re: What is the best modelstructure and routes?

I was wondering if your test failure is down to the params being passed back from the form to the controller or if the error is a result of the fields not being filled in correctly in your form

The log file entries would show the params and the save_and_open command will tell me what was filled in by the test on the form.

This could be your first genuine failing test or it could still be an issue with your tests.

Last edited by jamesw (2012-11-08 14:45:49)

What you want and what you need are too often not the same thing!
When your head is hurting from trying to solve a problem, stop standing on it. When you are the right way up you will see the problem differently and you just might find the solution.
(Quote by me 15th July 2009)

Re: What is the best modelstructure and routes?

I seem to do some duplicate work, which shouldn't be i suppose.

def create
    signupCustomer = Customer.new()
    signupCustomer.fill_standard(params[:customer][:id],params[:customer][:name], params[:customer][:email],params[:customer][:email_confirmation])
    
    ##Is customer valid?
    dbCustomer = signupCustomer.signup_is_valid
    if dbCustomer
        ##If there is already an authentication, go to the login screen
        if Authentication.exists?(:customer_id => dbCustomer.id)
          #Authentication shouldn't be existing!
          flash[:notice] = "This account already has a login, please check your e-mail for further information."
          redirect_to login_path
          return
        end
        
        unless dbCustomer.update_email(signupCustomer.email, signupCustomer.email_confirmation)
          @customer = dbCustomer
          render :edit
          return
        end
        
        ##No authentication, create one!
        if dbCustomer.create_authentication
            flash[:notice] = "Successfully created your account, check your mail for further information."
            redirect_to login_path
        else
            @customer = dbCustomer
            render :edit
        end
    else
      @customer = signupCustomer
      render :edit
    end
  end

But when I'm doing the update, the exact same code has to be executed, but I cant render within my model to have only 1 place to stock that code...
How can I solve this?!

Re: What is the best modelstructure and routes?

You need a boolean signup method on your customer model that does all that logic.
If the method returns true (success) then render the edit form else redirect to the login_path.
If you use the errors.add_to_base method in the signup method that reflect the varous flash messages you can render the error messages in your login_path view
There is an awefull lot of logic there, Do you have a spec for it?
I tried to write out how your code would work but got stuck as I don't have enough info around the difference between a signup_customer and a db_customer and what those various methods do that you use in the controller.
This is as far as I got

  def signup?(params = {})
      res = false
      self.fill_standard(params)
      if self.signup_is_valid? #Not sure what this method does but it should NOT return a customer object and it should be a private method
          if Authentication.exists?(:customer_id => dbCustomer.id)
              #Authentication shouldn't be existing!
              self.errors.add_to_base("This account already has a login, please check your e-mail for further information."
          else
              unless dbCustomer.update_email(signupCustomer.email, signupCustomer.email_confirmation)
                  res = true
              else
              
         end
     
      end
  end
What you want and what you need are too often not the same thing!
When your head is hurting from trying to solve a problem, stop standing on it. When you are the right way up you will see the problem differently and you just might find the solution.
(Quote by me 15th July 2009)

Re: What is the best modelstructure and routes?

This is a brief spec:

#A customer wants to signup on the customer portal
1. The user presses the signup button on the startscreen
2. The user has to fill in following fields in order to create a "new" customer authentication
  2.1 Fills in customer_id
  2.2 Fills in customer_name
  2.3 Fills in customer_email
  2.4 Fills in customer_email_confirmation
3. The user presses "create account"
4. If user with specifications ID and Name are found in the database (= dbCustomer.signup_is_valid)
  4.1 if the authentication with this customer_id is found
    4.1.1 Go to the login page and tell the customer that the account for this customer is already created
  4.2 if the given email (and confirmation) is correct
    4.2.1 update the customer Record (only the e-mail field)
  4.3 else
    4.3.1 show that the email/email-confirmation is not correct
  4.4 There is no authentication, so create an authentication
    4.4.1 Make a new authentication and fill it up with
      4.4.1.1 login
      4.4.1.2 password --> random generated password
      4.4.1.3 password_confirmation --> = password
      4.4.1.4 customer_id
    4.4.2 Get the contact for this person (always exists)
    4.4.3 Save the authentication and send emails to the customer and the contact person for that customer
  4.5 if there is an error on creating the authentication
    4.5.1 render the page again
  4.6 else
    4.6.1 go to the login path and tell the customer he is being emailed!
5. else
  5.1 render the page and show the errors

Hope this is somewhat explanatory smile

The signup_is_valid looks if this customer can be found.
Why should it be private?

  def signup_is_valid
    begin
      dbCustomer = Customer.find_by_id_and_name!(self.id, self.name)
      return dbCustomer
    rescue ActiveRecord::RecordNotFound
      self.errors.add :base, "Your customer number or name are wrong. Please try again or contact support."
      return false
    end
  end

Should be:

  def signup_is_valid
    begin
      Customer.find_by_id_and_name!(self.id, self.name)
      return true
    rescue ActiveRecord::RecordNotFound
      self.errors.add :base, "Your customer number or name are wrong. Please try again or contact support."
      return false
    end
  end

Greets

Last edited by ReBa (2012-11-14 04:29:00)

Re: What is the best modelstructure and routes?

That spec looks very thorough.

Should be:
  def signup_is_valid
    begin
      Customer.find_by_id_and_name!(self.id, self.name)
      return true
    rescue ActiveRecord::RecordNotFound
      self.errors.add :base, "Your customer number or name are wrong. Please try again or contact support."
      return false
    end
  end

It's bad proraming practice to break up the flow of proceures with return statements.
Setup a local variable and assign it an appropriate value under each condition and return it at the end of the method.

  def signup_is_valid
    res = false #Default to false and only set to true if a customer is found. No need to set to false in the rescue statement as it's already false
    begin
       Customer.find_by_id_and_name!(self.id, self.name)
       res = true
    rescue ActiveRecord::RecordNotFound
       self.errors.add :base, "Your customer number or name are wrong. Please try again or contact support."
    end
    return res #No need for the return statement. In Ruby the last line will be the result that is returned but I like to include the return for clarity and readability. This statement could just be "res" and nothing else.
  end

Becaus the spec is so large, nothing wrong with that. Many real world business logic functions involve huge amounts of logic, you should flow chart it.

What you want and what you need are too often not the same thing!
When your head is hurting from trying to solve a problem, stop standing on it. When you are the right way up you will see the problem differently and you just might find the solution.
(Quote by me 15th July 2009)