What am I doing wrong? [Rails, belongs_to] - ruby-on-rails

Stuck on nested forms..
Order model:
class Order < ActiveRecord::Base
belongs_to :user
accepts_nested_attributes_for :user
end
User mode:
class User < ActiveRecord::Base
has_many :orders, dependent: :destroy
accepts_nested_attributes_for :orders
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Form view:
=form_for #order do |order|
=order.fields_for :user, #order.user do |user|
.row
.col-md-3
.form-group
=user.label :first_name, "Name"
=user.text_field :first_name, :class => "form-control"
.col-md-3
.form-group
=user.label :last_name, "Last name"
=user.text_field :last_name, :class => "form-control"
.col-md-3
=user.label :email, "Email"
=user.text_field :email, :class => "form-control"
.col-md-3
=user.label :telephone, "Phone"
=user.text_field :telephone, :class => "form-control"
.row
.col-md-4.margin-top-15
=order.submit 'Send', :class => 'btn btn-success'
OrdersController:
class OrdersController < ApplicationController
def new
#order = Order.new
if user_signed_in?
user = current_user
else
user = User.new
end
end
def create
#order = Order.new order_attributes
#order.save
end
private
def order_attributes
params.require(:order).permit(:user_id, user_attributes: [:id, :user_id, :user, :first_name, :last_name, :email, :telephone, :password, :password_confirmation])
end
end
So this is what I am trying to do:
User model has devise. I want to create order and assign to it user_id. On submit it tells me "Unpermitted parameter: user". Order model creates its column, but nothing goes to user model.
What am I doing wrong?

Change:
params.require(:order).permit(:user_id, user_attributes: [:id,...
to:
params.require(:order).permit(:user_id, user: [:id,...

Remove :user from :user_attributes.
And I don't think :user_id is necessary.

Related

How can I make my polymorphic model work?

I've got two models User and Image as polymorphic association because I want my image model to reuse in other models.
class User < ApplicationRecord
has_one :cart
has_many :images, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :images
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
before_validation :set_name, on: :create
validates :name, presence: true
private
def set_name
self.name = "person#{rand(1000)}" if self.name.blank?
end
end
class Image < ApplicationRecord
mount_uploader :image, ImageUploader
belongs_to :imageable, polymorphic: true
end
And I made Image polymorphic: true and use carrierwave gem for creating uploader `mount_uploader mount_uploader :image, ImageUploader in Image model:image
class ImageUploader < CarrierWave::Uploader::Base
end
and I permit :image parameters to each model: User and Good,
module Admin
class UsersController < BaseController
before_action :set_admin_user, only: [:show, :edit, :update, :destroy]
def users_list
#admin_users = User.all.preload(:images).where(admin: true)
end
def show
end
def edit
end
def update
if #user.images.update(admin_user_params)
redirect_to admin_users_list_path, notice: 'User was successfully updated'
else
flash[:alert] = 'User was not updated'
end
end
def destroy
end
private
def set_admin_user
#user = User.find(params[:id])
end
def admin_user_params
params.require(:user).permit(:name, :email, images_attributes: [:image])
end
end
end
In my view form I've got the next code:
<%= form_for [:admin, #user], html: { multipart: true } do |f| %>
<%= f.label 'Name', class: 'form-group' %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.fields_for :images_attributes do |i| %>
<%= i.label :image %>
<%= i.file_field :image %>
<% end %>
<%= f.label 'Email', class: 'form-group' %>
<%= f.text_field :email, class: 'form-control' %>
<%= f.submit class: 'btn btn-oultline-primary' %>
<% end %>
but when I want to update user for exampletry to upload the image I've got the next:
Here is what I have as response
I can't saveupload my image. Why is that? I expect to have an insert into db but it doesn't happen and in db I've got no attached images.
Since you are adding multiple images, change your form to:
<%= i.file_field :image, multiple: true, name: "images_attributes[image][]" %>
And in the controller:
def edit
#image = #user.images.build
end
def update
if #user.images.update(admin_user_params)
create_user_images
redirect_to admin_users_list_path, notice: 'User was successfully updated'
else
flash[:alert] = 'User was not updated'
end
end
private
def admin_user_params
params.require(:user).permit(:name, :email, images_attributes: [:id, :user_id, :image])
end
def create_user_images
if params[:images_attributes]
params[:images_attributes]['image'].each do |i|
#image = #user.images.create!(:image => i)
end
end
end
Let me know if you still have problems after the edits :)

Rails 4, Devise, Nested attributes not saving to database

I am using devise for user authentication in a rails 4 app.
After the user registers, I am redirecting the user to a page which has some additional fields they can choose to populate. I have the form appearing correctly, but it is not saving the nested attribute to the database.
I have a model called "seeker_skill" which has this relation to user:
user has_many seeker_skills
seeker_skills belongs to user
user.rb
class User < ActiveRecord::Base
has_many :seeker_skills, dependent: :destroy
accepts_nested_attributes_for :seeker_skills, :reject_if => lambda { |a| a[:skill].blank? }, :allow_destroy => true
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
users_controller.rb
class UsersController< ApplicationController
def job_seeker_additional_fields
#user = current_user
#user.seeker_skills.build
#seeker_skill = current_user.seeker_skills.build
end
end
seeker_skill.rb
class SeekerSkill < ActiveRecord::Base
belongs_to :user
validates :skill, presence: true
end
seeker_skills_controller.rb
class SeekerSkillsController < ApplicationController
def create
#seeker_skill = current_user.seeker_skills.build(seeker_skill_params)
if #seeker_skill.save
redirect_to root_url
else
flash[:error] = "Invalid Input"
redirect_to myskills_path
end
end
def destroy
end
def new
#seeker_skill = current_user.seeker_skills.build
#user = current_user
end
private
def seeker_skill_params
params.require(:seeker_skill).permit(:skill)
end
end
I believe I have the permitted parameters set up correctly in the application controller.
application_controller.rb
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :role, :email,
:company, :password, :password_confirmation, :remember_me,
seeker_skills_attributes: [:id, :skill, :user_id, :_destroy]) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login,
:username, :role, :email, :company, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :bio,
:min_salary, :location, :radius, :role, :email, :company, :password, :password_confirmation,
:current_password, seeker_skills_attributes: [:id, :skill, :user_id, :_destroy]) }
end
end
Finally there is the form in the view: Eventually I will add option to add multiple skills at once.
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= f.fields_for(#seeker_skill) do |f| %>
<%= f.text_field :skill, placeholder: "Add skill" %>
<% end %>
<%= f.submit "Submit", class: "btn btn-large btn-primary" %>
<% end %>
What am I missing? I have set this up with a custom user authentication system but never with devise.
Change your nested fields call to:
<%= f.fields_for(:seeker_skill) do |f| %>
with a symbol, not the object. When created with object, it names the field from the object class name, so in result you got params[:user][:seeker_skill], which are then filtered by strong params. While run with symbol, it tries to execute method with given name, treats it as an object and if the form object defines <name>_attributes sets the subobject name to <name>_attributes.

track model not being created in my rails app

in my rails app, I am running into an issue. As a heads up I am using devise.
tracks_controller.rb
def new
#track = Track.new
end
def create
#track = current_user.tracks.build(params[:content])
if #track.save
flash[:success] = "Track created!"
redirect_to #user
else
render 'static_pages/home'
end
users_controller.rb
def show
#user = User.find(params[:id])
#tracks = #user.tracks
if signed_in?
#track = current_user.tracks.build
end
end
I am logged in as a current user, and when I try to add a new track (through the current user) it is not saving.. (and instead redirects to root_url)
track.rb
class Track < ActiveRecord::Base
attr_accessible :content
belongs_to :user
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :username, :email, :password, :password_confirmation, :remember_me
# attr_accessible :title, :body
validates :username, uniqueness: { case_sensitive: false }
has_many :tracks, dependent: :destroy
end
shared/_track_form.html.erb
<%= form_for(#track) do |f| %>
<div class="track_field">
<%= f.text_area :content, placeholder: "Upload a youtube song URL...", :id => "message_area" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
relavent section for /users/show.html.erb
<div class="span8">
<% if signed_in? %>
<section>
<%= render 'shared/track_form' %>
</section>
<% end %>
I believe the issue is in my TracksController #create method, however I just can't figure it out. any help is greatly appreciated, thanks!
In your controller create action change
#track = current_user.tracks.build(params[:content])
to this
#track = current_user.tracks.build(params[:track])
Since you used form_for(#track) the params hash will contain the :content field filled into the form.
The way you have it now the create action cant find the form :content because there isn't a form named content. content is an attribute of the Track model.

Controller not creating with association

I've got two models, Users and Organizations, which have a has_many relationship using an assignments table. I have a nested resource form when the user is created, which creates an associated organization just fine. However, when creating an organization, it doesn't associate it with the user.
Here's my relevant Organizations controller code:
def new
#organization = current_user.organizations.build
end
def create
#organization = current_user.organizations.build(params[:organization])
#organization.save
end
And my models:
Organizations Assignments
class OrganizationAssignment < ActiveRecord::Base
belongs_to :user
belongs_to :organization
attr_accessible :user_id, :organization_id
end
Organizations:
class Organization < ActiveRecord::Base
validates :subdomain, :presence => true, :uniqueness => true
has_many :organization_assignments
has_many :people
has_many :users, :through => :organization_assignments
attr_accessible :name, :subdomain
end
Users:
class User < ActiveRecord::Base
has_many :organization_assignments
has_many :organizations, :through => :organization_assignments
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
accepts_nested_attributes_for :organizations
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :organizations_attributes
# attr_accessible :title, :body
end
form view:
= form_for #organization, :html => { :class => 'form-horizontal' } do |f|
- #organization.errors.full_messages.each do |msg|
.alert.alert-error
%h3
= pluralize(#organization.errors.count, 'error')
prohibited this user from being saved:
%ul
%li
= msg
= f.label :name
= f.text_field :name
= f.label :subdomain
= f.text_field :subdomain
.form-actions
= f.submit nil, :class => 'btn btn-primary'
= link_to t('.cancel', :default => t("helpers.links.cancel")), organizations_path, :class => 'btn'
I'm able to associate the organizations fine after the fact in the console, so I'm pretty sure the relationships are set up correctly in the model. Is there anything else I'm missing?
From my experience with Rails, you can't expect the relation to be made that way. Try something like this.
def create
#organization = Organization.build(params[:organization])
#organization.save
current_user.organizations << #organization
end
You might alternatively keep your code as-is, but save current_user instead of #organization.
def create
#organization = current_user.organizations.build(params[:organization])
current_user.save
end

Controller not creating association

I've got two models, Users and Organizations, which have a has_many relationship using an assignments table. I have a nested resource form when the user is created, which creates an associated organization just fine. However, when creating an organization, it doesn't associate it with the user.
Here's my relevant Organizations controller code:
def new
#organization = current_user.organizations.build
end
def create
#organization = current_user.organizations.build(params[:organization])
#organization.save
end
And my models:
Organizations Assignments
class OrganizationAssignment < ActiveRecord::Base
belongs_to :user
belongs_to :organization
attr_accessible :user_id, :organization_id
end
Organizations:
class Organization < ActiveRecord::Base
validates :subdomain, :presence => true, :uniqueness => true
has_many :organization_assignments
has_many :people
has_many :users, :through => :organization_assignments
attr_accessible :name, :subdomain
end
Users:
class User < ActiveRecord::Base
has_many :organization_assignments
has_many :organizations, :through => :organization_assignments
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
accepts_nested_attributes_for :organizations
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :organizations_attributes
# attr_accessible :title, :body
end
form view:
= form_for #organization, :html => { :class => 'form-horizontal' } do |f|
- #organization.errors.full_messages.each do |msg|
.alert.alert-error
%h3
= pluralize(#organization.errors.count, 'error')
prohibited this user from being saved:
%ul
%li
= msg
= f.label :name
= f.text_field :name
= f.label :subdomain
= f.text_field :subdomain
.form-actions
= f.submit nil, :class => 'btn btn-primary'
= link_to t('.cancel', :default => t("helpers.links.cancel")), organizations_path, :class => 'btn'
I'm able to associate the organizations fine after the fact in the console, so I'm pretty sure the relationships are set up correctly in the model. Is there anything else I'm missing?

Resources