Create a controller and view - ruby-on-rails

Hello I have the following models.
The User Model:
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
has_one :user_informations
has_secure_password
end
The UserInformation Model:
class UserInformation < ActiveRecord::Base
belongs_to :user
attr_accessible :address, :address2, :business, :descripcion, :identification_number, :mobile_cell, :name, :phone_number
end
Now I need to create the view and the controller to create and update the user information, and I have many questions:
1) how can I generate the controller:
rails g controller UserInformations
o
rails g controller UserInformation
2) how my new, create and update action know the user ID.
3) how can I set the routes for this user information
Thanks. Maybe these are a basic question, but I'm new in rails and I don't know how to do all of this.
Thanks again for your help.

1) You have to use pluralize for controller, so rails g controller UserInformations will work.
2 + 3) You can set up Restful routes:
resources :users do
member do
get 'user_information'
end
end
With above routes you will have path users/:id/user_information, so you can know your user ID through params[:id], ex, in your create or update action you can use:
user = User.find(params[:id])
to find which user is shown informaton.

You'll need a user_id column in your user_information table and model.
1) rails g UserController
2) you can include the user_id as param, so for the new action it will be
def new
#user = User.find(param[:user_id])
#user_information = #user.user_information.new
end
the create and update actions would get the user id from the form params but you'll need to think about who is going to be using these actions and if you want to allow all users to update the information of other users. If not, you should have the user id as a hidden param and use a gem like cancan (https://github.com/ryanb/cancan) to restrict access
alternatively you can set them up as nested resources (http://railscasts.com/episodes/139-nested-resources)
3) for a simple resources you can add this to your routes.rb file
resource :user_information
or for nested you can do
resource :users do
member do
resource :user_information
end
end

First of all
in User Model, there should be
has_one :user_information
as there association name should be singular with has_one.
you can create controller by giving the command
rails g controller UserInformation
and it depends on you what name you want to give to you controller.
In new action you will have to find user by its id. You can store user id in session
after login. Or if you are saving user first time then you will have to pass user id.
In new action do
user = User.find(session[:id])
user.user_information.create(params[:user_information])
I think you need to study all this first. Go through some examples. Then try. It is too quick to ask here.

Related

Can't find where devise create method to create user

Updated
I want to add more details to this. I have a user model and this user model
has_many :trial_subscriptions
attr_accessible :trial_subscriptions_attributes
accepts_nested_attributes_for :trial_subscriptions, :allow_destroy => true
I am building a custom form so when a user enters a trial_email, the form will create a new user with an associated trial_subscription
The trial_subscription.rb model inherits from manual_subscription model and manual_subscription inherits from subscription model.
The subscription model
belongs_to :user
I need to build the associations from the has_many side. Now I am having trouble figuring out where to post the form (getting the #user to be editted) when devise is involve. I need to know where the create method is when the user gets created and hence my question below.
This will be a separate page from normal sign up in a /sales url so I can not add nested fields to the signup form.
The rails application that I am working on has devise installed on the user model.
In the routes
I have
devise_for :users, :controllers => {:registrations => "registrations"}
resources :users
the sign up form is in views/devise/registrations/new.html.erb
I have a users_controller.rb with a new and create method
in the users_controller.rb there is this before_filter
before_filter :authenticate_admin!
We have active admin installed. I am still quite new to the code. Since this filter exist I am sure the user is not getting created in this controller.
when I go to
/users/sign_up - there is the sign up page
if I do
/users/new - I am redirected to /users/sign_up
so I am guessing that the user is getting created in the registrations controller but the new method is
this
def new
session[:qbid] = params[:qbid]
session[:trial] = params[:trial]
session[:sublength] = params[:sublength]
if session[:trial] = true
#trial_flow = true
end
super
end
there is no User.new object getting passed to the view to get edited? I am guessing that devise doesn't need it.
I am getting confused on where the user is getting created because my task is to create a custom form which creates a new user.
I don't know where to post the form to? the registrations_controller?
The user has a has_many subscriptions association and I need to post a form that both create the user and its subscriptions.
You need to customize devise's registrations controller. See it's doc
Though the doc shows only how to customize the session controller (login), the steps are similar, you just need name your customized controller differently.
If you are wondering, you can see here how devises' controllers look.
When you are customizing those, you are going to use inheritance. That is another topic you should read about.

Rails: Add an existing child as a new association to parent model via ajax

I try to add an existing child model to the parent via ajax, by only providing the new id.
My models:
class User < ActiveRecord::Base
has_many :books
attr_accessible :books
end
class Book < ActiveRecord::Base
belongs_to: :user
end
In my html form the user is viewing a User and it can select an existing Book to add. This will result in an Ajax request. I would like to only send the new Book, and not all the already assigned books. E.g. the User model has already Books 1 and 2, and now to user selects Book 3 to also be assigned.
I can not find the correct structure of the parameters. If I use the following, it completely overwrites the current associations.
// Ajax parameters
user[books] = [3]
How should is build the parameters such that it only adds the new book? And as a follow-up, how can I build the parameters to remove only a single association?
You have to send only one "book_id" in request.
Then in controller:
# assuming params hash is { :book_id => 3 }
#book = Book.find params[:book_id]
#user.books << #book
...
# Removing
#user.books.delete(#book)
# In `update` action
params[:user][:book_ids] = (#user.book_ids + params[:user][:book_ids]).flatten
#user.update_attributes(params[:user])

how set curren_user_admin.id in model Post ??? I'm using ActiveAdmin + Cancan

I'm using ActiveAdmin + Cancan, i have this models
AdmiUser
Notice
I want set the id of the current_user_admin in Notice model before save a notice
class Notice < ActiveRecord::Base
belongs_to :admin_user
belongs_to :category
before_save :set_admin_user_id
def set_admin_user_id
self.admin_user_id = ? # maybe..! : current_admin_user.id
end
...
end
here is the link on github activeadmin-cancan-roles
I don't know ..!!! :(
You don't! Doing so would violate the principles of Model-View-Controller. Only the controller should know about the current user.
If you need to store the current admin user in a Notice instance, then just set it when you create it (which you're doing in the controller anyway, where you have access to who the current admin user is).

nested form & habtm

I am trying to save to a join table in a habtm relationship, but I am having problems.
From my view, I pass in a group id with:
<%= link_to "Create New User", new_user_url(:group => 1) %>
# User model (user.rb)
class User < ActiveRecord::Base
has_and_belongs_to_many :user_groups
accepts_nested_attributes_for :user_groups
end
# UserGroups model (user_groups.rb)
class UserGroup < ActiveRecord::Base
has_and_belongs_to_many :users
end
# users_controller.rb
def new
#user = User.new(:user_group_ids => params[:group])
end
in the new user view, i have access to the User.user_groups object, however when i submit the form, not only does it not save into my join table (user_groups_users), but the object is no longer there. all the other objects & attributes of my User object are persistent except for the user group.
i just started learning rails, so maybe i am missing something conceptually here, but i have been really struggling with this.
Instead of using accepts_nested_attributes_for, have you considered just adding the user to the group in your controller? That way you don't need to pass user_group_id back and forth.
In users_controller.rb:
def create
#user = User.new params[:user]
#user.user_groups << UserGroup.find(group_id_you_wanted)
end
This way you'll also stop people from doctoring the form and adding themselves to whichever group they wanted.
What does your create method look like in users_controller.rb?
If you're using the fields_for construct in your view, for example:
<% user_form.fields_for :user_groups do |user_groups_form| %>
You should be able to just pass the params[:user] (or whatever it is) to User.new() and it will handle the nested attributes.
Expanding on #jimworm 's answer:
groups_hash = params[:user].delete(:groups_attributes)
group_ids = groups_hash.values.select{|h|h["_destroy"]=="false"}.collect{|h|h["group_id"]}
That way, you've yanked the hash out of the params hash and collected the ids only. Now you can save the user separately, like:
#user.update_attributes(params[:user])
and add/remove his group ids separately in one line:
# The next line will add or remove items associated with those IDs as needed
# (part of the habtm parcel)
#user.group_ids = group_ids

Best practice: How to split up associations-functions in controllers with equal-access models

I have 2 equal-access models: Users and Categories
Each of these should have the standard-actions: index, new, create, edit, update and destroy
But where do I integrate the associations, when I want to create an association between this two models?
Do I have to write 2 times nearly the same code:
class UsersController << ApplicationController
# blabla
def addCategory
User.find(params[:id]).categories << Category.find(params[:user_id])
end
end
class CategoriessController << ApplicationController
# blabla
def addUser
Category.find(params[:id]).users << User.find(params[:user_id])
end
end
Or should I create a new Controller, named UsersCategoriesController?
Whats the best practice here? The above example doens't look very DRY.... And a new controller is a little bit too much, I think?
Thanks!
EDIT:
I need to have both of these associations-adding-functions, because f.e.
#on the
show_category_path(1)
# I want to see all assigned users (with possibility to assign new users)
and
#on the
show_user_path(1)
#I want to see all assigned categories (with possibility to assign new categories)
EDIT:
I'm taking about a HBTM relationship.
If you have a situation where you need to do this with has_and_belongs_to_many, you could take the approach you are currently using, or you could build this into your existing update actions.
When you add a habtm relationship, you will get an additional method on your classes...
class User < ActiveRecord::Base
has_and_belongs_to_many :categories
end
With this, you can do this:
user = User.find(params[:id])
user.category_ids = [1,3,4,7,10]
user.save
The categories with those ids will be set. If you name your form fields appropriately, the update can take care of this for you if you want to use checkboxes or multiselect controls.
If you need to add them one at a time, then the methods you've built in your original post are reasonable enough. If you think the repetition you have is a code smell, you are correct - this is why you should use the approach I outlined in my previous answer - an additional model and an additional controller.
You didn't mention if you are using has_and_belongs_to_many or if you are using has_many :through. I recommend has_many :through, which forces you to use an actual model for the join, something like UserCategory or Categorization something like that. Then you just make a new controller to handle creation of that.
You will want to pass the user and category as parameters to the create action of this controller.
Your form...
<% form_tag categorizations_path(:category_id => #category.id), :method => :post do %>
<%=text_field_tag "user_id" %>
<%=submit_tag "Add user" %>
<% end %>
Your controller...
class CategorizationsController < ApplicationController
def create
if Categorization.add_user_to_category(params[:user_id], params[:category_id])
...
end
end
then your categorization class...
class Categorization
belongs_to :user
belongs_to :category
def self.add_user_to_category(user_id, category_id)
# might want to validate that this user and category exist somehow
Categorization.new(:user_id => user_id, :category_id => category_id)
Categorization.save
end
end
The problem comes in when you want to send the users back, but that's not terribly hard - detect where they came from and send them back there. Or put the return page into a hidden field on your form.
Hope that helps.

Resources