Unsure about how to use rails 3 check_box - ruby-on-rails-3

I have a User form as follows, with a checkbox to set the user as admin:
<%= form_for #user do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation, "Confirmation" %><br />
<%= f.password_field :password_confirmation %>
</div>
<%= hidden_field_tag :group_id, #group.id %>
**<div class="field">
<%= f.check_box :admin %>
</div>**
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
My Users table is as follows
create_table "users", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "email"
t.string "encrypted_password"
t.string "salt"
t.boolean "admin", :default => false
t.integer "group_id"
end
And my User create action is as follows in my Users Controller
def create
#group = Group.find(params[:group_id])
#user = #group.users.build(params[:user])
if #user.save
flash[:success] = "You have created a new user"
redirect_to groups_path
else
#title = "Sign up"
render 'new'
end
end
But when I test user.admin for true, it doesn't show as true
<% #users.each do |user| %>
<li>
<%if user.admin == true %>
<%= link_to user.name, user %>
<% end%>
</li>
<% end %>
The form works fine otherwise, only the check_box doesn't set the user.admin to true. Have I missed a key step somewhere? thanks

Are you sure the value is getting set to true in the database? Check it out using dbconsole:
rails dbsconsole
If not, then you may need to make sure it's accessible in your User model:
attr_accessible :admin
Also, as a side note boolean values come with a bonus question mark method in ActiveRecord, so you could do this instead:
if user.admin?

Related

accepts_nested_attributes_for only display one record when used with has_many

My models
class Game < ApplicationRecord
has_many :rounds
accepts_nested_attributes_for :rounds
end
class Round < ApplicationRecord
belongs_to :game
end
controller
def new
#game = Game.new
3.times { #game.rounds.build }
end
view
<%= form_with scope: :game, url: games_path, local: true do |form| %>
<p>
<%= form.label :title %><br>
<%= form.text_field :title %>
</p>
<p>
<%= form.label :game_date %><br>
<%= form.date_field :game_date %>
</p>
<ul>
<%= form.fields_for :rounds do |builder| %>
<li>
<%= builder.label :title %>
<%= builder.text_field :title %>
<%= builder.label :order %>
<%= builder.text_field :order %>
</li>
<% end %>
</ul>
<p>
<%= form.submit %>
</p>
<% end %>
The above code only generates one "round" of record when new is building 3 records.
I am on rails 5.2.1
It is because you have a different object (formbuilder) when using form.
<%= form_with model: #game, local: true do |form| %>
Or
<%= form_with scope: #game, url: games_path, local: true do |form| %>
instead of
<%= form_with scope: :game, url: games_path, local: true do |form| %>
which produces the desire result. Have a look at this blog for better understanding.
It turns out you have to use form_for instead of the new form_with.

Devise nested form not creating profile

Rails 5.0.1
Devise 4.2.0
Hello, I'm building an app in which the user must fill a form to sign up, which includes the registration info for devise, and some personal info por their profile. I have made the models for user and profile, established their one to one relation, and added accept_nested_attributes_for :profile inside the user. I have also modified the registrations views to include f.fields_for for the profile, and until that point everything seems to work fine.
But, when I try to create a new user, and fill the required information, I get an error inside the view (from devise I guess) saying:
1 error prohibited this user from being saved
Profile user must exist
I have already followed many guides on how to create a nested form with devise, and none of them seem to have this issue, and I have also searched a lot with no answer. Here are some snippets from my registration controller, user and profile model, and registrations/new view:
registrations_controller
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
before_action :configure_account_update_params, only: [:update]
def new
build_resources({})
resource.build_profile
respond_with self.resource
end
protected
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up,
keys: [:email, :password,
:password_confirmation,
profile_attributes: [:name, :art_name,
:birth_date, :location]])
end
User model
class User < ApplicationRecord
has_one :profile, dependent: :destroy
before_create :build_profile
accepts_nested_attributes_for :profile
# Devise configuration.....
end
Profile model
class Profile < ApplicationRecord
belongs_to :user
end
Registrations/new view
<h2>Nueva Cuenta</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= f.fields_for :profile do |b| %>
<div class="field">
<%= b.label :name, "Nombre" %><br />
<%= b.text_field :name %>
</div>
<div class="field">
<%= b.label :art_name, "Nombre artistico" %><br />
<%= b.text_field :art_name %>
</div>
<div class="field">
<%= b.label :birth_date, "Fecha de nacimiento" %><br />
<%= b.date_field :birth_date %>
</div>
<div class="field">
<%= b.label :location, "Ubicacion" %><br />
<%= b.text_field :location %>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
My guess is that it has something to do with the sanitizers, I'm not completely sure how do I pass each attribute through, since most of the guides that explained this did with an older version of devise.
Thanks for your attention.
in your profile model, try this:
belongs_to :user, optional: true
it works for me

Getting attributes in nested model rails 3.2

I have two models user and profile.
I want to save the username and password in user and other user profile details in
profile.
Now,
The user model has:
has_one :profile
accepts_nested_attributes_for :profile
attr_accessible :email, :password,:profile_attributes
The profile model has
belongs_to :user
attr_accessible :firstname, :lastname
The user controller has
def new
#user = User.new
#profileattr = #user.build_profile
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to root_url, :notice => "user created successfully!"
else
render "new"
end
end
The view new.html.erb have fields for both user and profile.
view has:
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<%= f.fields_for #profileattr do |pf|%>
<p>
<%= pf.label :firstname %><br />
<%= pf.text_field :firstname %>
</p>
<p>
<%= pf.label :lastname %><br />
<%= pf.text_field :lastname %>
</p>
<% end %>
<p class="button"><%= f.submit %></p>
<% end %>
However,when I run this web application it shows error:
Can't mass-assign protected attributes: profile
on debug I found the user has attributes as:
:email:abc#gmail.com
:password:secret
:profile
---:firstname:abc
---:lastname:xyz
so,instead of expected params[:profile_attributes] the view returning params[:profile]
leading to mass-assignment error.so what is going wrong?
Did you try
<%= f.fields_for :profile do |pf|%>
?

How to flash error for particular validation

I am trying to flash messages in a form when they do not meet the validation requirements but can't work out how to achieve this.
I have the following setup:
models/item.rb
class Item < ActiveRecord::Base
attr_accessible :condition, :day, :description, :subtitle, :title
validates :user_id, presence: true
validates :title, presence: true
validates :description, presence: true, length: { minimum: 20 }
belongs_to :user
end
controllers/items_controller.rb
class ItemsController < ApplicationController
before_filter :authenticate_user!
def new
#item = Item.new
end
def show
#item = Item.find(params[:id])
end
def create
#item = current_user.items.build(params[:item])
if #item.save
flash[:success] = "Your item has been saved"
redirect_to root_path
else
render 'new'
end
end
def destroy
#item.destroy
redirect_back_or root_path
end
end
and finally views/items/new.html.erb
<h1>Items Base</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#item) do |f| %>
<%= f.label :title, "Title" %>
<%= f.text_field :title %>
<%= f.label :subtitle, "Subtitle" %>
<%= f.text_field :subtitle %>
<%= f.label :condition, "Condition" %>
<%= f.number_field :condition %>
<%= f.label :description, "Description" %>
<%= f.text_field :description %>
<%= f.label :day, "Day" %>
<%= f.text_field :day %>
<%= f.submit "List", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
Essentially I would like to be able to flash the message "Description too short!" when the user leaves it blank or below 20 characters, or flash the message "Title required" if it is left blank. Any thoughts on how best to achieve this. Also if anyone has any good resources on working with the flash it would be much appreciated. Thanks.
Here is how I do it:
Here is the form:
<%= form_for(#client) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :company_name %>
<%= f.text_field :company_name %>
<%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
<% end %>
And here is my error_messages partial:
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-error">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

Help to render a partial from fields_for

I'm using nested_attributes and trying to implement the add/remove fields on-the-fly throu ajax following Ryan Bates screencast about Nested Model (#196)
Doing this, it won't work, but when removing the "link_to_add_fields" line, it works fine.
The problem is that I'm don't know if I doing this all associations right.
<%= form_for(#item) do |f| %>
<% if #item.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#item.errors.count, "error") %> prohibited this item from being saved:</h2>
<ul>
<% #item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :item_type_id %><br />
<%= f.select :item_type_id, #item_types.collect { |p| [ p.title, p.id ]} %>
<br />
<%= f.fields_for :item_parts do |parts_form| %>
<%= render "item_part_fields", :p => parts_form %>
<% end %>
</div>
<%= link_to_add_fields "Add Part", f, :part %>
<div class="actions">
<%= button_for "Save Item", :class => 'positive pill button', :button_type => 'submit' %>
</div>
<% end %>
Actually my models are:
"ItemPart" model:
class ItemPart < ActiveRecord::Base
belongs_to :item
belongs_to :part
end
"Item" model:
class Item < ActiveRecord::Base
belongs_to :item_type
has_many :item_parts
has_many :parts, :through => :item_parts
accepts_nested_attributes_for :item_parts, :allow_destroy => true
after_save :save_id
validates :title, :presence => true
def save_id
item_part_attributes = [ { :item_id => self.id } ]
end
end
"Part" model:
class Part < ActiveRecord::Base
has_one :part_type
has_many :item_parts
has_many :items, :through => :item_parts
end
The error I'm getting doing this way:
undefined method `klass' for nil:NilClass
Extracted source (around line #26):
23: <%= render "item_part_fields", :p => parts_form %>
24: <% end %>
25: </div>
26: <%= link_to_add_fields "Add Part", f, :item %>
27: <div class="actions">
Application trace
app/helpers/application_helper.rb:44:in `link_to_add_fields'
app/views/items/_form.html.erb:26:in `block in _app_views_items__form_html_erb__1418129287024756954_2169222480__3228169100620818569'
app/views/items/_form.html.erb:1:in `_app_views_items__form_html_erb__1418129287024756954_2169222480__3228169100620818569'
app/views/items/edit.html.erb:3:in `_app_views_items_edit_html_erb___1857878264245794505_2169270380_890290209246324491'
Application_helper.rb
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new # error line :44
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')" )
end
After hours and hours doing tests and googling a lot, I get it finally solved.
Seems that I'd to use the same local variable name to render the partial used for the form_for and then use it again as a helper method parameter needed. (In this case, "f" variable.)
I pasting the cleaning working code below
<%= form_for(#item) do |f| %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :item_type_id %><br />
<%= f.select :item_type_id, #item_types.collect { |p| [ p.title, p.id ]} %><br />
</p>
<p>
<%= f.fields_for :item_parts do |parts_form| %>
<%= render "item_part_fields", :f => parts_form %>
<% end %>
</p>
<p><%= link_to_add_fields "Add Part", f, :item_parts %></p>
<p><%= button_for "Save Item", :class => 'positive pill button', :button_type => 'submit' %></p>
<% end %>
Hope this going to help someone someday :)
There is a mistake in your add more button. This should be,
<p><%= link_to_add_fields "Add Part", f, :item_parts %></p>
The association name should be the table name on which have many relation is.