views:

115

answers:

5

Hey!

I have users registration procedure on my app. But my users have to register with promo code. So I have model Promocodes for that:

  t.references :user #this is who have create that promo, e.g. Admin
  t.string :name #a "name" for promo, e.g. "some_promo"
  t.integer :allowreg #how much registrations  can be done using that promo key

So now, when registering, I have to check promo. But how it can be done?! Here is my view for signup form:

  <% form_for @user do |f| %>
   <%= f.error_messages %>
   <fieldset>
    <ol>
      <li>
        <%= f.label "Promo key" %>

       ??????????????????????????????????
                                        There have to be a field for promo key
                                       ???????????????????????????????????


      </li>
     <li>
      <%= f.label :login, 'Login' %>
      <%= f.text_field :login %>
     </li>
     <li>
      <%= f.label :email %>
      <%= f.text_field :email %>
     </li>
     <li>
      <%= f.label :password, "Pass" %>
      <%= f.password_field :password %>
     </li>
     <li>
      <%= f.label :password_confirmation, 'Pass again' %>
      <%= f.password_field :password_confirmation %>
     </li>
    </ol>
   </fieldset>
   <div class="buttons">
    <%= submit_tag 'Signup!' %>
   </div>
  <% end %>

Thank you!

A: 

Have a look at fields_for - I think that should help.

Andy Gaskell
May be so, I can't really understand for now how. Thanks anyway.
TJY
A: 

Ok. here is the solution:

On User model using combination of

  attr_accessor :promocode

and

  attr_accessible: promocode

let you to use :promocode as param. And you will get access to @user.promocode for example.

TJY
A: 

If you don't want to muck up your user model with the promocode attribute, I think you can use the text_field_tag (and corresponding [label_tag]) from within your form_for. Something like:

<% form_for @user do |f| %>
  <%= f.error_messages %>

  <%= label_tag "promo_key" %>
  <%= text_field_tag "promo_key" %>

  <%= f.label :login, 'Login' %>
  <%= f.text_field :login %>

  <%# ...other fields go here... %>

  <%= f.submit 'Signup!' %>
<% end %>

Then, in your controller's create action, you can simply access the entered promo code by checking params[:promo_code].

def create  
  @user = User.new(params[:user]) #build up the user object 
  promo_code = PromoCodes.find_by_name(params[:promo_code]) #find the promo code that user entered

  if promo_code.allow_reg == 0 #make sure that the code has uses left
    flash[:notice] = "That promo code has expired. Whoops!"
    render :action => 'new'
  else

    if @user.save 
      #i assume you want to decrement the allow_reg on a successful registration?
      promo_code.update_attribute :allow_reg, promo_code.allow_reg - 1

      flash[:notice] = "User account created! Please log in with your new account"  
      redirect_to login_url  
    else  
      render :action => 'new'  #user couldn't be saved. validation error?
    end 

  end 
end

Would that work too? (I'd probably consider moving the promocode checking out of the create action and into a before filter, to keep things cleaner.)

-John

John Reilly
A: 
Kuya
A: 

In your User model:

class User < ActiveRecord::Base
  has_one :promocode
  accepts_nested_attributes_for :promocode
end

Then in your view you can use:

<% f.fields_for :promocode do |promocode_form| %>
  <% promocode_form.text_field :code_key %>
<% end %>

In your promo code model you can write whatever validations you want (perhaps via a cusomt use def validate method), when your user controller action 'create' tries to save the user object it will also save/validate the promocode, find out more about it here:

http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

tsdbrown