Ok I've searched far and wide and can't find a solution that I can get working...so I decided to post here.
I have 2 models
Store
class Store < ActiveRecord::Base
attr_accessible :storeimage, :storename
belongs_to :user
validates :user_id, :presence => true
end
and
User
class User < ActiveRecord::Base
attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :userimage, :remove_userimage
has_secure_password
has_many :gears
has_many :comments, :dependent => :destroy
has_one :store, :dependent => :destroy
before_save :create_remember_token
require 'carrierwave/orm/activerecord'
mount_uploader :userimage, UserpicUploader
accepts_nested_attributes_for :store
...
end
When someone creates a new user account I need to automatically create a new store for that user I was thinking within the user form. So how can I create a new store object that's linked to the new user being created?
Here is my code from the User Controller for CreateAction
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
redirect_to #user, :flash => {:success => "Welcome to Equiptme"}
else
render 'new'
#title = "Sign up"
end
end
View
<div class="signup_container">
<div class="signup_container_interior">
<%= provide(:title, 'Sign up') %>
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div>
<div>
The form contains <%= pluralize(#user.errors.count, "error") %>.
</div>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :first_name %> <%= f.text_field :first_name, class: 'register_text_area' %>
</div>
</div>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :last_name %> <%= f.text_field :last_name, class: 'register_text_area' %>
</div>
</div>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :email %> <%= f.text_field :email, class: 'register_text_area' %>
</div>
</div>
<!--************STORE FIELDS ************** -->
<!--************STORE FIELDS END ************** -->
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :password %> <%= f.password_field :password, class: 'register_text_area' %>
</div>
</div>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :password_confirmation %> <%= f.password_field :password_confirmation, class: 'register_text_area' %>
</div>
</div>
<div class="actions">
<%= f.submit "Create Account", class: 'register_button' %>
</div>
<% end %>
</div>
</div>
You can use the build_association method created along with the has_one relationship between users and stores:
def create
#user = User.new(params[:user])
#user.build_store
# etc
end
If you don't need the store until you've saved the user, you might also use create_association:
if #user.save
#user.create_store
# etc
end
You may want to take a look at this:
http://railscasts.com/episodes/196-nested-model-form-part-1
Related
it is my login application .please anyone can explain me how can i check login validations
pbl01/config/routes.rb
Rails.application.routes.draw do
devise_for :users, :controllers => {
:registrations => 'users/registrations'
}
resources :import,only: [:index,:create]
root 'root#index'
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
pbl01/app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
before_action :configure_sign_in_params, only: [:create]
def new
end
def create
authorized_user=User.authenticate(params[:userid],params[:password])
if authorized_user
flash[:notice] = "Wow Welcome again, you logged in as"
else
flash[:notice] = "Invalid Username or Password"
flash[:color]= "invalid"
render "new"
end
end
pbl01/app/models/user.rb
require 'csv'
class User < ApplicationRecord
validates :userid, :presence => true,
validates :password, :presence => true,
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
def email_required?
false
end
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
users = find_by(userid: row["userid"]) || new
users.attributes = row.to_hash.slice(*updatable_attributes)
users.password= row["password"]
users.save!
end
end
def self.updatable_attributes
["userid", "name", "email"]
end
end
pbl01/app/views/devise/sessions/new.html.erb
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<% if #user.errors.any? %>
<div class="field">
<%= f.label :userid %><br />
<%= f.text_field :userid, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
<% for message_error in #user.errors.full_messages %>
<li>* <%= message_error %></li>
<% end %>
</div>
<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end -%>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
I believe you should change to something like this.
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url:
session_path(resource_name)) do |f| %>
<% if #user.errors.any? %>
<% for message_error in #user.errors.full_messages %>
<li>* <%= message_error %></li>
<% end %>
<% end %>
<div class="field">
<%= f.label :userid %><br />
<%= f.text_field :userid, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
I have a program that allows users to enter their song for a certain event. You must enter in the partycode for that event in order for it to submit. Here is a screenshot of what it looks like:
When I submit it gives me this error:
Here is what my SongsController looks like:
class SongsController < ApplicationController
def new
#song = Song.new
end
def create
current_event = Event.find(song_params[:event_id])
#song = current_event.songs.build(song_params)
if #song.save
flash[:success] = "Success"
redirect_to event_path(#song.event)
else
flash[:error] = "Failed"
end
end
def destroy
end
private
def song_params
params.require(:song).permit(:event_id, :artist, :title, :genre)
end
end
event model
class Event < ApplicationRecord
belongs_to :user
validates :name, presence: true
validates :partycode, presence: true, length: {minimum: 5}
has_many :songs, dependent: :destroy
end
song model
class Song < ApplicationRecord
belongs_to :event
validates :artist, presence: true
validates :title, presence: true
end
new.html.erb(song)
<br>
<br>
<h1> Member page </h1>
<div class ="container">
<div class="jumbotron">
<h2> Select an event to add songs to: </h2>
<%= form_for Song.new do |f| %>
<%= f.collection_select(:event_id, Event.all, :id, :name) %>
<h3> Enter your song </h3>
<%= form_for Song.new do |f| %>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
<h2> Enter the partycode for that event: </h2>
<%= form_for Event.new do |f| %>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
<% end %>
<% end %>
</div>
</div>
What can I do to make this functionality of my website work? Any help is greatly appreciated thanks
I see many form_for nesting on your views. It's impossible. Only one submit for a form.
I think you may want to change your _form.html.erb
<div class ="container">
<div class="jumbotron">
<h2> Select an event to add songs to: </h2>
<%= form_for #song do |f| %>
<%= f.collection_select(:event_id, Event.all, :id, :name) %>
<h3> Enter your song </h3>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
<h2> Enter the partycode for that event: </h2>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
You have completely messed up your form. Ideally you should have one form but here you have just kept one form within another form using form_for.
I would recommend you to have a look at the form_for documentation .
I am creating an application through which a user will be able to create an account. When they create an account, in the same form they will be able to create an organization that will then be tied to their user. Once that user has created their account (and an organization) other users will be able to create an account and use an "access code" to join that organization as well. Looking at the code may explain it better.
The reason i'm posting on SO is because i have a feeling there is a better / more efficient way to do it than what i am currently doing. I'm using nested_forms (maybe not correctly) and i don't think i'm doing the associations the right way because, for example, i haven't been able to get the edit form to fill out the organization fields.
I am using sorcery for the authentication as well.
users_controller.rb
def new
#user = User.new
end
def create
#user = User.new(user_params)
if params[:user][:organization][:name].blank?
flash.now[:error] = "You must specify an organization name."
render :new
else
if params[:user][:organization][:access_code].blank?
# create new organization
#access_code = "#{SecureRandom.urlsafe_base64(16)}#{Time.now.to_i}"
#organization = Organization.create(:name => params[:user][:organization][:name], :access_code => #access_code)
#user.organization_id = #organization.id
#user.is_admin = true
else
# try and add someone to an organization
#organization = Organization.find(:all, conditions: ["name = ? AND access_code = ?", params[:user][:organization][:name], params[:user][:organization][:access_code]])
if #organization.empty?
flash.now[:error] = "No organization has been found with that name and access code."
render :new
return
else
#user.organization_id = #organization.first.id
end
end
if #user.save
user = login(#user.email, params[:user][:password])
if user
flash[:success] = "Your account has been successfully created!"
redirect_to admin_dashboard_path
end
else
flash.now[:error] = "Something went wrong! Please try again."
render :new
end
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.is_admin?
if params[:user][:organization][:name].blank? && params[:user][:organization][:name] != #user.organization.name
params[:user][:organization][:name] = #user.organization.name
end
if params[:user][:organization][:access_code].blank? && params[:user][:organization][:access_code] != #user.organization.access_code
params[:user][:organization][:access_code] = #user.organization.access_code
end
#organization = Organization.find(params[:user][:organization_id])
#organization.name = params[:user][:organization][:name]
#organization.access_code = params[:user][:organization][:access_code]
#organization.save
end
if #user.update(user_params)
flash[:success] = "Your settings have been updated!"
redirect_to edit_admin_user_path(#user.id)
else
flash.now[:error] = "Something went wrong! Please try again."
render :edit
end
end
private
def user_params
params.require(:user).permit(:organization_id, :email, :password, :password_confirmation, :full_name, :remember_me, {:organization_attributes => [:name, :website, :description, :access_code]})
end
users.rb
class User < ActiveRecord::Base
authenticates_with_sorcery!
belongs_to :organization
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates_presence_of :full_name
validates_presence_of :email
validates_uniqueness_of :email, :on => :create
validates_format_of :email, :with => VALID_EMAIL_REGEX, :on => :create
validates_presence_of :password, :on => :create
validates_confirmation_of :password
end
organization.rb
class Organization < ActiveRecord::Base
authenticates_with_sorcery!
has_many :users, :dependent => :destroy
accepts_nested_attributes_for :users
validates_presence_of :name
end
new.html.erb
<% provide(:title, 'Create a User') %>
<h1>Create a User</h1>
<p>Use the form below to create an account.</p>
<%= nested_form_for([:admin, #user], html: {role: "form"}) do |f| %>
<%= render "shared/error_messages", obj: #user %>
<fieldset>
<legend>User Information</legend>
<div class="form-group">
<%= f.label :full_name, "Full Name" %>
<span class="help-block">How should others see you?</span>
<%= f.text_field :full_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<span class="help-block">Your email address is used as your login.</span>
<%= f.text_field :email, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
</fieldset>
<%= f.fields_for :organization do |o| %>
<fieldset>
<legend>Associated Organization</legend>
<div class="form-group">
<%= o.label :name, "Organization Name" %>
<span class="help-block">This is the name of the organization you are a part of.</span>
<%= o.text_field :name, class: "form-control" %>
</div>
<div class="form-group">
<%= o.label :access_code, "Organization Access Code" %>
<span class="help-block">Leaving this field blank will setup a new organization.</span>
<%= o.text_field :access_code, class: "form-control" %>
</div>
</fieldset>
<% end %>
<div class="form-actions">
<%= f.submit "Create Account", class: "btn btn-primary" %>
<%= link_to "Cancel", :back, class: "text-btn" %>
</div>
<% end %>
edit.html.erb
<% provide(:title, "Edit User: #{#user.full_name} (#{#user.organization.name})") %>
<h1>Edit User: <%= #user.full_name %> (<%= #user.organization.name %>)</h1>
<p>Use the form below to manage your account.</p>
<%= nested_form_for([:admin, #user], html: {role: "form"}) do |f| %>
<%= render "shared/error_messages", obj: #user %>
<fieldset>
<legend>User Information</legend>
<div class="form-group">
<%= f.label :full_name, "Full Name" %>
<span class="help-block">How should others see you?</span>
<%= f.text_field :full_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<span class="help-block">Your email address is used as your login.</span>
<%= f.text_field :email, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, placeholder: "leave blank to keep password unchanged", class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
</fieldset>
<% if #user.is_admin? %>
<%= f.fields_for :organization do |o| %>
<fieldset>
<legend>Associated Organization</legend>
<div class="form-group">
<%= o.label :name, "Organization Name" %>
<span class="help-block">This is the name of the organization you are a part of.</span>
<%= o.text_field :name, class: "form-control", value: #user.organization.name %>
</div>
<div class="form-group">
<%= o.label :access_code, "Organization Access Code" %>
<span class="help-block">Leaving this field blank will setup a new organization.</span>
<%= o.text_field :access_code, class: "form-control", value: #user.organization.access_code %>
</div>
</fieldset>
<% end %>
<%= f.hidden_field :organization_id %>
<% end %>
<div class="form-actions">
<%= f.submit "Update User", class: "btn btn-primary" %>
<%= link_to "Cancel", :back, class: "text-btn" %>
</div>
<% end %>
Ok, those are all the files making it happen. Now, i have the application doing almost everything i need it to do but this doesn't feel like production-level code to me.
One issue i know i am having is that if a user types something in the organization field and nothing else the controller will create and save the organization and then render the form back with the user validation errors. I don't want it to save the organization if there are validation errors in the user model.
I'm really just asking for advice if there is a better way of doing what i am trying to do. If you can't tell exactly what i'm trying to do with this code or have any questions please let me know!
Take a look at this post: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
Of particular interest will be the section on "3. Extract Form Objects".
I'm new in rails and currently trying to create an app but I can't seem to make it work. Here's my setup in model.
class User < ActiveRecord::Base
has_one :doctor, dependent: :destroy
accepts_nested_attributes :doctor
end
class Doctor < ActiveRecord::Base
belongs_to :user, :dependent => :destroy
end
In my users_controller, here's my code:
class UsersController < ApplicationController
def show
#user = current_user
# render text: #user.inspect
end
def new
#user = User.new
#user.build_doctor`
end
def create
# binding.pry
#user = User.new(user_params)
if #user.save
sign_in #user
redirect_to dashboard_path
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:role, :lastname, :firstname, :middlename, :email, :password, :password_confirmation, :doctor_attributes => [:institution, :license_number])
end
end
And my view:
<ul id="cbp-bislideshow" class="cbp-bislideshow">
<li>
<%= image_tag "blur1.jpg" %>
</li>
<li>
<%= image_tag "blur2.jpg" %>
</li>
</ul>
<% provide(:title, 'Sign Up') %>
<%= form_for(#user) do |f| %>
<div class="sign-up-wrapper divided-wrapper cf">
<div class="left-section">
<h3 class="section-title">JOIN US AND LET'S CHANGE THINGS</h3>
<div class="row">
<div class="w49 pull-left">
<%= f.text_field :firstname, class: "input-text personal ", placeholder: 'FIRSTNAME' %>
</div>
<div class="w49 pull-right">
<%= f.text_field :lastname, class: "input-text personal", placeholder: 'LASTNAME' %>
</div>
<%= f.hidden_field :role, value: :doctor %>
</div>
<div class="row">
<%# f.text_field :specialization, class: "input-text personal ", placeholder: 'SPECIALIZATION' %>
</div>
<%= f.fields_for :doctors do |p| %>
<div class="row">
<%= p.text_field :institution, class: "input-text personal ", placeholder: 'INSTITUTION' %>
</div>
<div class="row">
<%= p.text_field :license_number, class: "input-text personal ", placeholder: 'LICENSE NUMBER' %>
</div>
<% end %>
<span class="remind bottom-message"> ONCE INSIDE DON'T FORGET TO UPDATE YOUR PROFILE WITH MORE DETAILS </span>
</div>
<div class="right-section">
<h3 class="section-title"></h3>
<div class="row">
<%= f.text_field :email, class: "input-text personal ", placeholder: 'EMAIL' %>
</div>
<div class="row">
<%= f.password_field :password, class: "input-text personal ", placeholder: 'PASSWORD' %>
</div>
<div class="row">
<%= f.password_field :password_confirmation, class: "input-text personal ", placeholder: 'CONFIRM PASSWORD' %>
</div>
<div class="row cf">
<%= f.submit class: 'btn-join btn', value: 'JOIN NOW' %>
</div>
<div class="row">
SIGN UP WITH FACEBOOK / TWITTER ACCOUNT?
</div>
</div>
</div>
<% end %>
Everytimie I execute these pieces, only the user model gets populated but not the doctors table? Is there something wrong on my code?
EDIT
Changed doctors_attributes to doctor_attributes
changed #user.doctor.build`to #user.build_doctor
In the logs. I saw this error ---> Unpermitted parameters: doctors
So in theory, I think we know what's the problem, but I don't know how to fix this in the strong_parameters. Haven't tried a strong_parameter with accepted_nested_attributes_for in rails yet and this is my first time. Any solution?
In the fields_for, replace :doctors with :doctor. Remember that you're doing a 1 to 1 relationship.
In your user_params model, the attribute doctors_attributes should be doctor_attributes since it's a has_one relationship. If it was a has_many relationship, it would be doctors_attributes. The part before _attributes would be whatever the association is named.
Another note: If you want to be able to update the doctor from the user form, you should also include the id in the doctor_attributes array. Though now that I think of it, it might only be a requirement on has_many nested associations. I've never tried doing a has_one without including the id.
I have two models, user and treating (which you can think of as a message).
User:
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
has_many :sent_treatings, :foreign_key => "requestor_id", :class_name => "Treating", dependent: :destroy
has_many :received_treatings, :foreign_key => "requestee_id", :class_name => "Treating", dependent: :destroy
end
Treating:
class Treating < ActiveRecord::Base
attr_accessible :intro, :proposed_date, :proposed_location
validates :intro, presence: true, length: { maximum: 190 }
validates :requestor_id, presence: true
validates :requestee_id, presence: true
belongs_to :requestor, class_name: "User"
belongs_to :requestee, class_name: "User"
default_scope order: 'treatings.created_at DESC'
end
I'm having trouble in my treatings controller setting 'requestee':
class TreatingsController < ApplicationController
before_filter :signed_in_user
def create
requestee = ?
requestor = current_user
#received_treating = requestee.received_treatings.build(params[:treating])
#received_treating.requestor = requestor
if #received_treating.save
flash[:success] = "Treating request sent!"
redirect_to users_path
else
render 'static_pages/home'
end
end
end
The question mark I tried to replace with: User.find(params[:id]), hoping that the user in the current 'users/show' view would be found, but I get this error:
Couldn't find User without an ID
I also tried User.find(params[:treating][:requestee_id]), but this didn't work either. Any ideas?
Thanks!
EDIT:
views/shared/_treating_form.html.erb (this references #received_treating in the users controller, show action):
<div class="field">
<%= f.text_area :intro, placeholder: "Write your introduction here..." %>
</div>
<%= f.submit "Send", class: "btn btn-large btn-primary" %>
EDIT: adding other user profile page:
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
<% if signed_in? %>
<section>
<%= render 'shared/treating_form' %>
</section>
<% end %>
</aside>
<div class="span8">
<% if #user.received_treatings.any? %>
<h3>Treating requests (<%= #user.received_treatings.count %> received)</h3>
<ol class="treatings">
<%= render #received_treatings %>
</ol>
<%= will_paginate #received_treatings %>
<% end %>
</div>
</div>
I think just adding #user.id in a hidden_field would work.
<%= f.hidden_field :requestee_id, :input_html => { :value => #user.id }
<div class="field">
<%= f.text_area :intro, placeholder: "Write your introduction here..." %>
</div>
<%= f.submit "Send", class: "btn btn-large btn-primary" %>
You could also populate the field doing
<%= form_for #user.received_treatings.build do %>
<%= f.hidden_field :requestee_id %>
....
On the controller just do
#received_treating = current_user.sent_treatings.build params[:treating]
I have some doubts if this works but I think it should help you out.