ActiveModel::UnknownAttributeError unknown attribute 'avatar' - ActiveStorage - ruby-on-rails-5

Currently I'm trying to attach an :avatar field on a Profile. I get the following error:
However, following the docs I added the relationshipt of :avatar to Profile.
models/profile.rb
class Profile < ApplicationRecord
belongs_to :user
has_one_attached :avatar
end
I also add :avatar in the strong params. In the Profile controllers.
class ProfilesController < ApplicationController
def create
#profile = current_user.create_profile(profile_params)
end
##
private
def profile_params
params.require(:profile).permit(:full_name, :city, :bio, :avatar)
end
end
I wonder if the issue is because of the association between User and Profile. A user has one profile and profile belongs to user.
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :photos
has_one :profile
end
I request in the profiles/new.html.erb as a file attachement:
<%= form_for #profile do |f| %>
<div class="form-group">
<%= f.label :avatar %>
<%= f.file_field :avatar, as: :file, class: "form-control" %>
</div>
I see that in the params that the file is in avatar which is why I find so confusing that it doesn't recognize :avatar as an attribute.
Started POST "/profiles" for 127.0.0.1 at 2018-09-22 17:55:26 -0400
Processing by ProfilesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==", "profile"=>{"avatar"=>#<ActionDispatch::Http::UploadedFile:0x007ff62db322b8 #tempfile=#<Tempfile:/var/folders/86/g7_xcx392qn815kmkcm55ydc0000gn/T/RackMultipart20180922-10194-awlxd1.png>, #original_filename="profile.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"profile[avatar]\"; filename=\"profile.png\"\r\nContent-Type: image/png\r\n">
I was able to upload attachement for another model so it's not something with the installation. Any ideas why I'm getting this error?

Related

How to create new records with nested attributes in a ruby on rails "has many through" relationship?

I need some advice on building a has many through relationship between USER, THING and EXTRA models.
My USER model is slightly modified inside Devise gem and is noted as Creator whereas other models belonging to USER receive :created_things form.
In my app, USERS create THINGS can later add EXTRAS to their THINGS.
I chose has many through because I want to have unique data on all three models and be able to call both THINGS and EXTRAS from the USER "CREATOR" model.
I have built this many different ways and after 10 years of solving my problems by reading stackoverflow, I am finally submitting this request for support! Thank you for your help.
I have tried creating user and extra references on the THING model and declaring nested attributes in the USER and THING model. I have tried several examples from stackoverflow inside the create and new methods but nothing seems to work.
class User < ApplicationRecord
has_many :created_things, class_name: Thing, foreign_key:
:creator_id, :dependent => :destroy
has_many :extras, through: :created_things
accepts_nested_attributes_for :extras, :reject_if => :all_blank,
allow_destroy: true
class Thing < ApplicationRecord
belongs_to :creator, class_name: User
has_many :extras
accepts_nested_attributes_for :extras, :reject_if => :all_blank,
allow_destroy: true
class Extra < ApplicationRecord
belongs_to :creator, class_name: User, inverse_of: :thing
belongs_to :created_things
Members Index.html.erb
<% if thing.extras.exists? %>
<% thing.extras.each do |extra| %>
<%= extra.title %> <%= link_to "[+]", edit_extra_path(extra) %>
<% end %>
<% else if thing.extras.empty? %>
<%= link_to "+1 EXTRA", new_extra_path(current_user) %>
<% end %>
<% end %>
class MembersController < ApplicationController
before_action :authenticate_user!
def index
#user = current_user
#created_extras = #user.extras
#created_things = #user.created_things
end
class ExtrasController < ApplicationController
def new
#extra = Extra.new
end
def create
#extra = current_user.extras.build(extra_params)
if #extra.save
I am able to create a new EXTRA but the :thing_id remains nul as it does not display when called on the show extra view. Therefore I am not surprised that when I return to the member index page that my thing.extras.exists? call is returning false and the created extra never displays under the THING view. My attempts to modify the extra controller have failed and I some of my reading sugested the extras controller is not necessary in this relationship so I am really at a loss on how this is built. I'm assuming I am missing something in new and create methods maybe in things or user controller? Perhaps I'm missing something in routes resources? Any advice is greatly appreciated. Thank you.
Ok, I figured it out. I really didn't need has many through for this model and I did a lot of testing of the syntax on each model.rb and in the end was able to figure it out from this stackoverflow . . .
[Passing parent model's id to child's new and create action on rails
Here are my the various parts of setting up a has many and belongs to relationship with nested attributes.
class Thing < ApplicationRecord
belongs_to :creator, class_name: User
has_many :extras, inverse_of: :thing, :dependent => :destroy
accepts_nested_attributes_for :extras, allow_destroy: true
class Extra < ApplicationRecord
belongs_to :thing, inverse_of: :extras
extras_controller.rb
class ExtrasController < ApplicationController
def new
#extra = Extra.new(thing_id: params[:thing_id])
end
def create
#user = current_user
#extra = Extra.new(extra_params)
#extra.user_id = #user.id
if #extra.save
flash[:success] = "You have added a new Extra!"
redirect_to #extra #extras_path later
else
flash[:danger] = "The form contains errors"
render :new
end
end
edit.html.erb things
<% if #thing.extras.exists? %>
<p>current extras associated with <%= #thing.title %>: </p>
<% #thing.extras.each do |extra| %>
<p><%= extra.title %> <%= link_to "[+]", edit_extra_path(extra) %>
/ <%= link_to "[-]", extra_path(extra), method: :delete %> </p>
<% end %>
<% end %>
<%= link_to "+1 EXTRA", new_extra_path(thing_id: #thing.id) %>
<%= render 'things/form' %>

Rails 3 my first nested form doesnt work - Can't mass-assign protected attributes

I'm creating my first nested form in Rails 3.2.13. User is registering and he fill email, password and address information and company information.. but the error is showing while user click on submit. Error is at the bottom.
Im not sure about this line: attr_accessible :address_attributes, :company_attributes
which i read it could help but it doesnt and i have addresses in the view but address in the model because of one-to-one relationship but if i have <%= f.fields_for :**address** do |builder| %> the form doesnt show up.
Please what i have to do ? :-)
The post sends then
"companies"=>{"name"=>"Companyname"
User model
class User < ActiveRecord::Base
attr_accessible ...
has_many :orders
belongs_to :address
belongs_to :company
accepts_nested_attributes_for :address, :company
attr_accessible :address_attributes, :company_attributes
Company model
class Company < ActiveRecord::Base
attr_accessible ...
has_many :users
validates_presence_of ...
end
Address model
class Address < ActiveRecord::Base
attr_accessible ...
has_many :orders, :foreign_key => 'payment_address_id'
has_many :orders, :foreign_key => 'delivery_address_id'
has_many :users
validates_presence_of ...
end
new.html.erb (creating new user)
<%= form_for #user do |f| %>
...
<%= f.fields_for :addresses do |builder| %>
...
<% end %>
<%= f.fields_for :companies do |builder| %>
...
<% end %>
<%= f.submit %>
<% end %>
error while i click on submit
Can't mass-assign protected attributes: addresses, companies
EDIT:
First mistake: i changed in Class User
belongs_to :address
belongs_to :company
on
has_one :address
has_one :company
and in Address and Company model i edit
has_many :users
on
belongs_to :user
but nested forms doesnt show up in the view.. i tried edit Users Controller by adding .build method
def new
#user = User.new
#user.company.build
#user.address.build
end
but im getting new error
undefined method `build' for nil:NilClass
please what i have to do now ?
I had a case like this a day ago, and that's what I used.
class User
attr_accessible :name, :email, :company_attributes, :address_attributes
has_one :company
accepts_nested_attributes_for :company
end
and EmailSetting:
class Company
belongs_to :user
end
after this I can run in console:
User.new.build_company
as for form:
<%= form_for #user do |f| %>
<%= f.fields_for :company do |builder| %>
<%= f.text_field :name %>
<% end %>
<% end %>
in controller you just initialize the #user variable, no need to do #user.company.build or #user.address.build

Generating Multiple Association instances using fields_for and partial only shows one instance

Previously I was able to render multiple instances of a particular association (Generating multiple roles that belong to a team [Team has-many Roles - Role belongs to Team] but after making some changes to the layout it no longer does. I have read through many related threads but none seem to solve my issue.
I have a multi-model form and I am trying to build multiple role associations and have them render multiple times in the project creation view. The problem I run into is it will only render once.
#projects_controller.rb
def new
#user = current_user
#project = Project.new
#team = Team.new
#team = #project.build_team
#Default - New Project generates two roles through a team
2.times{#team.roles.new
role = #team.roles.build}
end
#Models
class Project < ActiveRecord::Base
has_one :team, dependent: :destroy
has_many :roles, :through => :team
accepts_nested_attributes_for :team, :allow_destroy => :true
end
class Team < ActiveRecord::Base
attr_accessible :name, :roles_attributes
validates :project, presence: true
belongs_to :project
has_many :roles, dependent: :destroy
accepts_nested_attributes_for :roles, :allow_destroy => :true
end
class Role < ActiveRecord::Base
belongs_to :team
end
#Views
#new.html.erb
<%= form_for :project do |f| %>
<%= render 'fields', :project_form => f %>
<%= content_tag(:button, content_tag(:span, "Create Project"), {:class => "btn- cma-2 bolds", :type=>:submit}) %>
<% end %>
#_fields.html.erb
<%= project_form.fields_for :roles do |f| %>
<%= render 'shared/role_fields', :role_form => f %>
<% end %>
#_role_fields.html.erb
<div class="formAreaWhite clearfix">
<div class="width350 fleft">
<p class="blue">Title:</p>
<div class="formArea"><%= role_form.collection_select(:role_title_id, #roletitles, :id, :title, {:prompt => "Select a Role"}, {:class=>"formSelect", :size => '1'}) %>
</div>
<p><span class="blue">Skills:</span>6/6</p>
</div>
<div class="width350 fright">
<p class="blue">Duties:</p>
<div class="formArea">
<div class="formArea"><%= role_form.text_area :duty, :class=>"text300" %></div>
</div>
</div>
I realized the issue. I removed the fields_for :team tag when I was making updates to the template since I wanted team values to be hidden but the association to exist. Apparently the team instance must appear in the view in order for the role associations to be built.
Once this tag was added back into the view the instances of the roles generated as expected.

Rails scoped form not assigning belongs_to

I have two models in Rails 3 - a User model and a Profile model.
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
end
class Profile < ActiveRecord::Base
belongs_to :user
end
They are scoped in my routes.rb file, as such:
resources :users do
resources :profiles
end
So now, my form to create a profile reads like this (Using SimpleForm):
<%= simple_form_for([#user, #profile]) do |f| %>
<%= f.error_notification %>
...(Other Inputs)
<% end %>
However, the user ID doesn't seem to be automatically sent to the profile model as I had assumed. Do I have to set that manually through the controller? Or am I missing something?
You should start by making sure that the relationship between User and Profile is indeed working correctly. You've actually put "has_one :user" in your User model, when I think you mean:
class User < ActiveRecord::Base
has_one :profile, :dependent => :destroy
end
In order to send the user ID with the form, the form should be on a page with a URL of something like "localhost:3000/users/5/profiles/new" which you can link to with the helper "new_user_profile_path(5)", for a user with ID 5.
When you submit the form, it will hit the create action in your ProfilesController. The following should result in the creation of the profile:
def create
#user = User.find(params[:user_id])
#profile = #user.build_profile(params[:profile])
#profile.save!
end
add :method => :post to your form since ur html request is GET which should be POST
simple_form_for([#user, #profile], :method => :post) do |f| %>

2 models in a form in rails 3

I am very new to rails development.
I am creating a simple backend for my portfolio site.
I am not sure about the title of this question. A previous question I asked maybe too convoluted. So I am simplifying it.
Im using 3 models: Post, Attachment, Attachment_Category
I have a form that I use to:
Draft the post with a title, content and a category.
Display attachment categories in a drop down (slideshow, image, video)
Upload the attachment(s).
I have implemented steps 1 and 2.
For step 3: I want it so that when I finally hit submit on the form, the attachment_category_id is saved to the attachment table.
I have the following relationships:
Post.rb
class Post < ActiveRecord::Base
has_many :attachment_categories, :through => :attachments
has_many :attachments,:dependent => :destroy
accepts_nested_attributes_for :attachments
validates_presence_of :title, :content, :category
end
Attachment.rb
class Attachment < ActiveRecord::Base
belongs_to :post
belongs_to :attachment_category
#paperclip
has_attached_file :photo, :styles =>{
:thumb => "100x100#",
:small => "400x400>"
}
end
Attachment_category.rb
class AttachmentCategory < ActiveRecord::Base
has_many :posts , :through => :attachments
has_many :attachments
validates :category_name, :presence =>true
end
So I have accomplished Steps 1, parts of step 2 and step 3.
With my solution, I am able to upload just one attachment.
But it works: The attachment gets saved to the Attachments table with the post_id and the attachment_category_id.
The following code is from _form.html.erb which gets sent to post_controller.rb.
Truncated code:
.....
<%= f.fields_for :attachments do |attach| %> <br>
<%= attach.collection_select :attachment_category_id, AttachmentCategory.all, :id, :category_name %>
<%= attach.file_field :photo %> <br>
<% end %>
.....