user.rb
class User < ActiveRecord::Base
# attr_accessible :title, :body
#validate :username ,:first_name ,:last_name ,:email ,:password ,:phone ,:location ,:require => true
# validates :username,:require => true
validates :username, :presence => true
has_many :ads
#validates :phone , :presence => true
attr_accessor :password,:password_confirmation
validates_confirmation_of :password
attr_protected :hashed_password ,:salt
users_controller
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = 'User successfully created.'
redirect_to :action => 'index'
else
render :action => 'index'
end
end
def new
if session[:user_id]
flash[:notice] = "You have already registered"
redirect_to(:controller => 'main',:action => 'index')
end
#user = User.new
end
alias :register :new
registration_form
<%= form_for #user do |f| %>
<%= f.error_messages %>
<table>
<tr>
<th>
<%= f.label :first_name %>
</th>
<td>
<%= f.text_field :first_name ,:placeholder => 'Please enter your real name.' %><br/>
</td>
</tr>
<tr>
<th>
<%= f.label :last_name %>
</th>
<td>
<%= f.text_field :last_name ,:placeholder => 'Please enter your real name.' %><br/>
</td>
</tr>
<tr>
<th>
<%= f.label :username %>
</th>
<td>
<%= f.text_field :username ,:placeholder => 'Enter your username here'%>
</td>
</tr>
<tr>
<th>
<%= f.label :email%>
</th>
<td>
<%= f.text_field :email ,:placeholder => 'sample#sample.com' %><br/>
</td>
</tr>
<% if !session[:user_id] %>
<tr>
<th>
<%= f.label :password %>
</th>
<td>
<%= f.password_field :password ,:placeholder => 'EnterPassword' %><br/>
</td>
</tr>
<tr>
<th>
<%= f.label :password_confirmation,'Confirm Password' %>
</th>
<td>
<%= f.password_field :password_confirmation ,:placeholder => 'Confirm password' %><br/>
</td>
</tr>
<% end %>
<tr>
<th>
<%= f.label :phone %>
</th>
<td>
<%= f.text_field :phone ,:placeholder => '09351270000' %><br/>
</td>
</tr>
<tr>
<th>
<%= f.label :location %>
</th>
<td>
<%= f.text_field :location ,:placeholder => 'Your address' %><br/>
</td>
</tr>
<tr>
<td></td> <td> <%= f.submit !session[:user_id] ? 'Register' : 'Save changes',:class => 'button',:style => 'height:50px' %></td>
</tr>
</table>
<% end %>
doubt
when i am logging in and updating user information using the same form its working fine , but when i am creating new user , i am redirected to users/index , while i am supposed to be registered
This basically means that the #user.save fails. There can be many reasons for this, it is hard to tell exactly what this is, since you don't give any error messages. The most probable case, I think, you are running into now is that you are trying to set a field (column of the user model) which is not accessible by the attr_accessible field.
Since you have commented that line out you are telling rails that there exists no fields in the user model which can be mass assigned. This is what happens when you call User.create(params[:user])
So to fix you problem now, try uncommenting your attr_accessible and add all the fields you need to set a user. In your case this would be:
attr_accessible :first_name, :last_name, :username, :email, :password, :phone, :location
I suggest you find some information on what attr_accessible and these others do. It is handy to know how these work.
Related
I am creating a hierarchical list of values (id, code, name, parent_id) for which the code is the business key. This means that when a user wants to attach a value to a parent, he fills in a parent_code field, and before save the model associates the parent value id. The value.rb model has a virtual attribute: parent_code, and the following before_save action:
class Value < ActiveRecord::Base
extend CsvHelper
# This virtual attribute allows user to ignore parent value id
attr_accessor :parent_code
### scope
# Value is linked to a list which belongs to the correct scope
### before filter
before_save :set_parent_id # user only inputs parent code
### validation
validates :code, presence: true
validates :name, presence: true
belongs_to :values_list
has_many :subs, :class_name => "Value", :foreign_key => :parent_id
belongs_to :superior, :class_name => "Value", :foreign_key => :parent_id
### private functions definitions
private
### before filters
def set_parent_id
self.level = 1
if not self.parent_code.blank?
#parent = Value.where("code = ? and values_list_id = ?", self.parent_code, self.values_list_id).first
self.parent_id = #parent.id
self.level = #parent.level.next
end
end
end
This model is used as nested object of a values_list model. This works fine at creation, and produces the expected result.
But when editing a record, the parent_code attribute is by no way initialized, and thus now shown in the input field. Here is the nested form:
<table class="table table-striped table-condensed">
<tr align="left">
<th></th>
<% if #values_list.is_hierarchical %>
<th> <%= t('ParentCode') %> </th>
<th> <%= t('Level') %> </th>
<% end %>
<th> <%= t('Code') %> </th>
<th> <%= t('Value') %> </th>
<th> <%= t('Description') %> </th>
</tr>
<%= f.nested_fields_for :values, #values_list.values.order(:code), wrapper_tag: 'tr' do |value| %>
<td><%= value.remove_nested_fields_link {image_tag("remove.png")} %></td>
<% if #values_list.is_hierarchical %>
<td><%= value.text_field :parent_code, ***# code to initialise #*** %> </td>
<td><%= value.text_field :level, disabled: true %> </td>
<% end %>
<td><%= value.text_field :code %> </td>
<td><%= value.text_field :name %> </td>
<td><%= value.text_field :description %> </td>
<% end %>
</table>
How can I initialise the input field with myvalue.superior.code ?
Thanks a lot!
You could access the form object that you're using in your f.nested_fields_for and set the value that way probably.
<%= f.nested_fields_for :values, #values_list.values.order(:code), wrapper_tag: 'tr' do |value| %>
...
<td><%= value.text_field :parent_code, value: value.object.superior.code %> </td>
<td><%= value.text_field :level, disabled: true %> </td>
...
Lets say I have three objects/models; years, cars, and parts. Now, I have cars belong_to parts. The thought on this was that a part may be part of many cars but a car has only one of that part at a given time. and years has_many cars through car_years. I have successfully nested the cars form in the years form. However, when I try to nest the parts form in the cars form and create a new year I get cannot mass assign protected: parts. But, I can create a new car and it will successfully create the new part. I would like to know if I am on the right track or should I be looking elsewhere to solve this. I got the idea from rails cast #196.
Year model
class Year < ActiveRecord::Base
attr_accessible :year, :cars_attributes
has_many :car_years
has_many :cars, :through => :machine_years
accepts_nested_attributes_for :car_years,
:reject_if => lambda { |a| a[:num_cars].blank? },
:allow_destroy => true
accepts_nested_attributes_for :cars,
:reject_if => lambda { |a| a[:doors].blank? },
:allow_destroy => true
end
Car model
class Machine < ActiveRecord::Base
attr_accessible ..., :part_id, :part_attributes
has_many :car_years
has_many :years, :through => :car_years
belongs_to :part
accepts_nested_attributes_for :car_years
accepts_nested_attributes_for :years
accepts_nested_attributes_for :part,
:reject_if => lambda { |a| a[:name].blank? }
end
Parts Model
class Part < ActiveRecord::Base
attr_accessible :desc, :name
has_many :machines
end
Year_form View
<%= form_for(#year) do |f| %>
<% if #year.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#year.errors.count, "error") %> prohibited this year from being saved:</h2>
<ul>
<% #year.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :year %><br />
<%= f.date_select :year, :start_year => 1940, :end_year => Time.now.year, :discard_day => true, :discard_mon th => true %>
</div>
<h3>Cars</h3>
<div>
<%= f.fields_for :cars do |builder| %>
<%= render 'car_fields', :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add Car", f, :cars %></p>
</div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Car_fields.html.erb
<div class="field">
<h3>New Car</h3>
<table>
<tbody>
<tr>
<th><%= f.label :name %></th>
<th><%= f.label :model %></th>
<th><%= f.label :part_id %></th>
</tr>
<tr>
<td><%= f.text_field :name %></td>
<td><%= f.text_field :model %></td>
<td>
<%= f.fields_for :part do |builder| %>
<%= render "cars/parts_fields", :f => builder %>
<% end %>
</td>
<td><%= f.number_field :memory_id %></td>
</tr>
<tr>
<th><%= f.label :install_dt, "Install Date" %></th>
<th></th>
<th><%= f.label :production_dt, "Production Date" %></th>
<th></th>
<th><%= f.label :remove_dt, "Remove Date" %></th>
</tr>
<tr>
<td><%= f.date_select :install_dt, :start_year => 1940, :end_year => Time.now.year %></td>
<td></td>
<td><%= f.date_select :production_dt, :start_year => 1940, :end_year => Time.now.year %></td>
<td></td>
<td><%= f.date_select :remove_dt, :start_year => 1940, :end_year => Time.now.year %></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th><%= f.label :history %></th>
<th></th>
<th><%= f.label :design %></th>
<th></th>
<th><%= f.label :notes %></th>
</tr>
<tr>
<td><%= f.text_area :history, :rows => 4 %></td>
<td></td>
<td><%= f.text_area :design, :rows => 4 %></td>
<td></td>
<td><%= f.text_area :notes, :rows => 4 %></td>
</tr>
</tbody>
</table>
<div style="padding: 2px;">
<%= f.label :image %><br />
<%= f.text_field :image %>
</div>
<%= link_to_function "remove", "remove_fields(this)" %>
</div>
cars/part_fields.html.erb
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %><br />
<%= f.label :desc %><br />
<%= f.text_area :desc, :rows => 3 %>
</div>
Hard to tell without seeing any of you code. However the following error cannot mass assign protected: parts means that you should add attr_accessible :parts to your model in order to be able to do something like this:
a_part = Part.new
another_part = Part.new
Car.new(parts: [a_part, another_part])
Otherwise, without it, you would have to do:
c = Car.new
c.parts << a_part
c.parts << another_part
OK, so the solution was in another post:
Getting fields_for and accepts_nested_attributes_for to work with a belongs_to relationship
In the car_fields form I needed to call
<%= f.fields_for :part_attributes do |builder| %>
not
<% =f.fields_for :parts do |builder| %>
However, now when I look at the year edit screen the part fields are empty, but the part_type does exist
I have a nested table called products nested under the parties table and one of the comluns is "brand". A product has a quantity, color and "brand". For "brand" I want the user to be able to do a multiple selection and collection on as many brands as the users want per product. How would I do this? I installed the "rails chosen gem", but it seems I need allot more than that.
Is it even possible for one column in a table to have multiple collection per user and product? Also it seems I should use indexing?
Code:
Product.rb:
class Product < ActiveRecord::Base
attr_accessible :party_id, :party, :id, :brand, :color, :name, :quantity
belongs_to :party
BRAND_TYPES = ["Hugs", "Kisses", "Love" ]
end
Party.rb:
class Party < ActiveRecord::Base
validates :user_id, presence: true
attr_accessible :name, :products_attributes, :products, :user_id
belongs_to :user
has_many :products
accepts_nested_attributes_for :products, allow_destroy: true
end
_product_fields.html.erb:
<table>
<tr>
<td> <%= f.label :name, "Product Name" %> </td>
<td> <%= f.text_field :name %> </td>
<td> <%= f.label :color, "Color" %> </td>
<td> <%= f.text_field :color %> </td>
<td> <%= f.label :Quantity, "Quantity" %> </td>
<td> <%= f.text_field :quantity %> </td>
<td> <%= f.label :brand, "Brand" %> </td>
<td> <%= f.select :brand, Product::BRAND_TYPES, :multiple => true %> </td>
<td> <%= f.link_to_remove "Remove this task" %></td>
</tr>
</table>
Thanks, I appreciate it.
I have the following models
class GymUser < ActiveRecord::Base
belongs_to :user
belongs_to :gym
end
class User < ActiveRecord::Base
has_many :gym_users
has_one :gym
attr_accessible :gym_users_attributes, :gym_users
accepts_nested_attributes_for :gym_users
end
I have a form for a new user, with a nested model gym_user. I want to make sure the user doesn't exist already. This is what I'm trying:
def create_member
#user = User.new(params[:user])
#user.generate_password
#dupe = User.find_all_by_email(#user.email)
if(#dupe)
#gym_user = GymUser.new(params[:user][:gym_users_attributes])
#gym_user.user_id = #dupe.id
elsif #user.save
#gym_user = #user.gym_users.order('created_at DESC').first
#gym = Gym.find(#gym_user.gym_id)
end
end
I know there's only one nested model here, but I can't figure out how to access those nested parameters.
Here's the form itself
<%= form_for #user, :as => :user, :remote => true, :url => { :controller => 'users', :action => 'create_member'} do |f| %>
<table border="0" cellpadding="10" cellspacing="0">
<tr>
<td colspan="2">
<%= f.label :name %><br />
<%= f.text_field :name %>
</td>
<td colspan="2">
<%= f.label :email %><br />
<%= f.text_field :email %>
</td>
</tr>
<% f.fields_for :gym_users do |builder| %>
<tr>
<td>
<%= builder.label :role_id, "Role" %><br />
<%= builder.collection_select(:role_id, #roles, :id, :name, {:include_blank => true}, {:onchange => "new_member_role_changed()"}) %>
<%= builder.hidden_field :gym_id, :value => #gym.id %>
</td>
<td>
<%= builder.label :item_id, "Membership Level" %><br />
<%= builder.collection_select(:item_id, #gym.membership_items, :id, :name, {:include_blank => true}) %>
</td>
<td>
<%= builder.label :has_monthly_billing, "Recurring Billing?" %><br />
<%= builder.radio_button :has_monthly_billing, "1" %>Yes
<%= builder.radio_button :has_monthly_billing, "0" %>No
</td>
<td>
<%= builder.label :billing_date %><br />
<%= builder.collection_select(:billing_date, (1..31).to_a, :to_s, :to_s, {:include_blank => true}) %>
</td>
</tr>
<tr>
<td colspan="4">
<%= f.submit %>
Cancel
</td>
</tr>
<% end %>
</table>
<% end %>
I found the answer. I'm not sure if this is the best way but it works
params[:user][:gym_users_attributes].values.first
Your association should be
has_one :gym, :through => gym_users
Also, can you post your form paramaters?
Your focus is on not allowing creation of duplicate users, and you are using email to verify this. You should rather use the helper
validates_uniqueness_of :email
in your User model. As you have a nested attribute, your object will be created only after Rails validates that a user with same email doesn't exist already.
I hope I understood your problem right.
I am struggling to get the nested form rendered with belongs_to association.
I was expecting the address fields in the "_form.html.erb" (below) to be rendered correct, but apparently it is not, and i just cant wrap my head around it to figure why!
Rails version: 3.09
here is the code.
Model:
Store.rb
class Store < ActiveRecord::Base
has_and_belongs_to_many :products
belongs_to :store_address, :foreign_key => "address_id", :class_name => "Address"
......
end
Address doesn't have any reference to Store model (it is independent)
Controller
stores_controller.rb
def new
#store = Store.new
#store.build_store_address
respond_with(#store)
end
View
new.html.erb
<% form_for(#store, :url => collection_url) do |f| %>
<%= render :partial => "form", :locals => { :f => f } %>
<p class="form-buttons">
<%= button t('continue') %>
</p>
<% end %>
_form.html.erb
<%=t(:store_name)%> : <%= text_field :store, :name %>
<%=t(:store_admin_email)%> : <%= text_field :store, :admin_email %>
<fieldset>
<legend><label><%=t(:address)%></label></legend>
<% f.fields_for :store_address do |address_form| %>
<table>
<tbody><tr>
<td width="200"><label><%=t(:line_1)%></label></td><td>
<%= address_form.text_area :address1, :rows => 2%>
</td>
</tr>
<tr>
<td><label><%=t(:line_2)%></label></td><td>
<%= address_form.text_area :address2, :rows => 2 %>
</td>
</tr>
<tr>
<td><label><%=t(:city)%></label></td><td>
<%= address_form.text_field :city %>
</td>
</tr>
.......
This renders the store name. but nothing on the address side. please help!
I think you missed an = at <% f.fields_for .... It should be <%= f.fields_for... .
This has happened to me so often in the past, missing this one thing, and then wondering why the nested form would not render.