Rails 7 - has_many_attached delete old attachment when new is loaded - ruby-on-rails

I'v got problem with Active Storage under Rails 7.
I read some posts but all are about Rails 5-6 and some methods was depreciated since then.
Problem - when I try to upload second photo, old is deleted. Why? How to fix this?
I have model:
class Profile
has_many_attached :photos
has_one_attached :avatar
in controller:
class ProfilesController < ApplicationController
def update
Rails.logger.debug params.inspect
#profile = current_user.profile
#profile.update(profiles_params)
private
# Only allow a list of trusted parameters through.
def profiles_params
params.require(:profile).permit(:id, :email, :marketing,
:marketing_second, :terms,
:personal_data,
:birthdate, :avatar, :photos )
end
in view:
<%= form_for #profile do |f| %>
<div class='upload_container'>
<%= f.file_field :photos, accept:'image/*',
:class=>'file_field_custom', required: true %>
<%= f.button "Upload", type:'submit', :class=>'photos_submit_button' %>
</div>
<% end %>
This was removed from Rails 7:
config.active_storage.replace_on_assign_to_many = false
logs:
#<ActionController::Parameters {"_method"=>"patch",
"authenticity_token"=>"y5n4UgRhRWFB9Q0L3J1roxK3dhuijRQk7Fng6sjHU52G0KDs9OJlYt8nmshG8HYnlrk7JB9x3QHDO8_GQnDwsA", "profile"=>{"photos"=>#<ActionDispatch::Http::UploadedFile:0x00007f9773f3db78 #tempfile=#Tempfile:/tmp/RackMultipart20230119-3094-gapmw4.jpg, #original_filename="saturn-planet-3200-1200-1966.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name="profile[photos]"; filename="saturn-planet-3200-1200-1966.jpg"\r\nContent-Type: image/jpeg\r\n">}, "controller"=>"profiles", "action"=>"update", "id"=>"abcd"} permitted: false>
[1m[36mProfile Load (0.6ms)[0m [1m[34mSELECT profiles.* FROM profiles WHERE profiles.user_id = 1 LIMIT 1[0m
↳ app/models/user.rb:59:in `profile'
[1m[36mActiveStorage::Attachment Destroy (4.4ms)[0m [1m[31mDELETE FROM
`active_storage_attachments` WHERE `active_storage_attachments`.`id` = 334[0m
↳ app/controllers/profiles_controller.rb:133:in `update'
Why action Destroy is fired.

#profile.photos.attach(params[:profile][:photos]) in update action of your controller

Related

Couldn't find User without an ID in form object

Could you help me? I got an error Couldn't find User without an ID, I was thinking about make like a blog service, I wanted to implement nest attribute without accepts_nested_attributes_for, so I've been using
form object, but I couldn't send form object user's parameter,
controller
class BlogsController < ApplicationController
before_action :authenticate_user!
def index
#current = current_user
end
def new
#blogs = BlogForm.new
end
def create
#blogs = BlogForm.new(blog_params)
if #blogs.save
redirect_to user_blogs_path
else
end
end
def edit
end
def show
end
private
def blog_params
params.require(:blog_form).permit(:title , :content , :user_id)
end
end
form html
<%= form_with model: #blogs , url: user_blogs_path,local: true do |f| %>
<% f.label :title %>
<%= f.text_field :title %>
<% f.label :content %>
<%= f.text_area :content %>
<% f.label :user_id %>
<% f.hidden_field :user_id , value: current_user.id%>
<%= f.submit "create", class: "btn btn-primary" %>
<% end %>
blog_form
class BlogForm
include ActiveModel::Model
attr_accessor :title, :content, :user_id
def to_model
#user = User.find(user_id)
#blogs = #user.blogs.new(title: title , content: content , user_id: user_id)
end
def save
return false if invalid
to_model.save
end
end
blogs.rb
class Blog < ApplicationRecord
belongs_to :user
validates :title ,presence: true
validates :content ,presence: true
end
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :blogs
def email_required?
false
end
def email_changed?
false
end
def will_save_change_to_email?
false
end
end
log
ActionView::Template::Error (Couldn't find User without an ID):
1: <%= form_with model: #blogs , url: user_blogs_path,local: true do |f| %>
2:
3: <% f.label :title %>
4: <%= f.text_field :title %>
app/forms/blog_form.rb:6:in `to_model'
app/views/blogs/shared/_form.html.erb:1
app/views/blogs/new.html.erb:4
Started GET "/users/1/blogs/new" for 127.0.0.1 at 2020-01-19 16:29:03 +0900
Processing by BlogsController#new as HTML
Parameters: {"user_id"=>"1"}
Rendering blogs/new.html.erb within layouts/application
Rendered blogs/shared/_form.html.erb (Duration: 3.0ms | Allocations: 1143)
Rendered blogs/new.html.erb within layouts/application (Duration: 10.5ms | Allocations: 1228)
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.0ms | Allocations: 1715)
ActionView::Template::Error (Couldn't find User without an ID):
1: <%= form_with model: #blogs , url: user_blogs_path,local: true do |f| %>
2:
3: <% f.label :title %>
4: <%= f.text_field :title %>
app/forms/blog_form.rb:6:in `to_model'
app/views/blogs/shared/_form.html.erb:1
app/views/blogs/new.html.erb:4
after, I tried coreyward's way, but I couldn't,
rocessing by BlogsController#new as HTML
Parameters: {"user_id"=>"1"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Rendering blogs/new.html.erb within layouts/application
Rendered blogs/shared/_form.html.erb (Duration: 6.9ms | Allocations: 1082)
Rendered blogs/new.html.erb within layouts/application (Duration: 9.4ms | Allocations: 1166)
Completed 500 Internal Server Error in 114ms (ActiveRecord: 2.3ms | Allocations: 11134)
ActionView::Template::Error (Couldn't find User without an ID):
1: <%= form_with model: #blogs , url: user_blogs_path(#user),local: true do |f| %>
2:
3: <% f.label :title %>
4: <%= f.text_field :title %>
app/forms/blog_form.rb:6:in `to_model'
app/views/blogs/shared/_form.html.erb:1
app/views/blogs/new.html.erb:4
The route helper user_blogs_path probably expects an argument for the user. Something like this:
user_blogs_path(#user)
Which goes in this line:
<%= form_with model: #blogs , url: user_blogs_path(#user),local: true do |f| %>
This is just a really strange and awkward way of doing a nested resource. This really has very little to do with nested attributes which used when you need to create or update two (or more) associated records in the same request.
# routes.rb
resources :users do
resources :blogs,
only: [:new, :show, :create],
shallow: true
end
class BlogsController
before_action :set_user, only: [:new, :create]
# GET /blogs/1
def show
#blog = Blog.find(params[:id])
end
# GET /users/1/blogs/new
def new
#blogs = #user.blog.new
end
# POST /users/1/blogs
def create
#blogs = #user.blog.new(blog_params)
if #blog.save
redirect_to #blog
else
render :new
end
end
private
def set_user
#user = User.find(params[:user_id])
end
def blog_params
params.require(:blog).permit(:title, :content)
end
end
<%= form_with model: [#user, #blog], local: true do |f| %>
<% f.label :title %>
<%= f.text_field :title %>
<% f.label :content %>
<%= f.text_area :content %>
<%= f.submit "create", class: "btn btn-primary" %>
<% end %>

Having trouble submitting nested resource through form [Rails 5]

I have a Document that has_many Section, and each section has_one Comment. I want to be able to create both sections and comments in the Document show view, but I'm having trouble getting comments to go through.
Here's the relevant code with the closest I've got:
class CommentsController < ApplicationController
def create
#section = Section.find(params[:id])
#section.comment.create(comment_params)
end
private
def comment_params
params.require(:comment).permit(:body)
end
end
The routing:
resources :documents, shallow: true do
resources :sections do
resources :comments
end
end
And the view with the form:
# app/views/documents/show.html.erb
<% #document.sections.each do |section| %>
<%= section.body %>
<% if section.comment %>
<p>
<%= section.comment %>
</p>
<% else %>
<%= form_with url: section_comments_path(section.id), scope: 'comment' do |form| %>
<%= form.text_field :body, placeholder: "Comment" %>
<%= form.submit %>
<% end %>
<% end %>
<% end %>
It all seems to check out for me, but when I try to post a comment, here's what I get:
Started POST "/sections/51/comments" for ::1 at 2019-05-24 23:29:06 +0000
Processing by CommentsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>[...], "comment"=>{"body"=>"asdas"}, "commit"=>"Save comment", "section_id"=>"51"}
Section Load (0.5ms) SELECT "sections".* FROM "sections" WHERE "sections"."id" = ? LIMIT ? [["id", 51], ["LIMIT", 1]]
comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."section_id" = ? LIMIT ? [["section_id", 51], ["LIMIT", 1]]
Completed 500 Internal Server Error in 11ms (ActiveRecord: 0.9ms)
NoMethodError (undefined method `create' for nil:NilClass):
app/controllers/comments_controller.rb:4:in `create'
Any ideas?
A has_one relationship returns the object itself. Therefore, #section.comment.create(comment_params) will not work because #section.comment is nil. Instead, try something like...
def create
#section = Section.find(params[:section_id])
#comment = Comment.create(comment_params)
#section.comment = #comment
...
end
Or, as stated in the Rails Guides...
When initializing a new has_one or belongs_to association you must use
the build_ prefix to build the association, rather than the
association.build method that would be used for has_many or
has_and_belongs_to_many associations. To create one, use the create_
prefix.
Which would look like this
def create
#section = Section.find(params[:section_id])
#section.create_comment(comment_params)
...
end
You likely need to change:
#section.comment.create(comment_params)
to:
#section.comments.create(comment_params)
If that doesn't work, try:
#section.comment.create!(comment_params)
and see what the exception says

Rails Devise - Update User with Associated Model

Good day,
I have a devise users model and in edit user page I want to add a custom field called "add verification documents" which takes in multiple documents(pdf's) that are uploaded in edit user page. A User can upload multiple documents.
# user.rb
class User < ActiveRecord::Base
has_many :verification_documents
end
# routes.rb
devise_for :users,
path: '',
path_names: {sign_in: 'login', sign_out: 'logout',sign_up: 'sign-up', edit: 'profile'},
controllers: {
omniauth_callbacks: 'omniauth_callbacks',
registrations: 'registrations'
}
My Requirement is similar to
Rails Devise - Register User with Associated Model ,
But Instead of address attributes, here I want to upload multiple verification verification documents to the verification_documents model during update action of the devise user model.
# views/devise/registrations/edit.html.erb
<div class="row">
<%= form_for(resource, as: resource_name,
url: registration_path(resource_name),
html: { method: :put },
multipart: true) do |f| %>
<div class="form-group">
<%= f.text_field :fullname, autofocus: true,
placeholder: "Full Name *", class: "form-control" %>
</div>
<div class="form-group">
<%= f.email_field :email, placeholder: "Email *",
class: "form-control" %>
</div>
<span class="btn btn-default btn-file btn-green pad_small">
Upload Verification Documents
<input type="file" accept="application/pdf" name="input-file-preview"/>
<%= file_field_tag "verification_documents[]", type: :file, multiple: true %>
</span>
<div class="actions">
<%= f.button "Save", class: "btn btn-green pad_small" %>
</div>
</div>
# verification_document.rb
class VerificationDocument < ActiveRecord::Base
belongs_to :user
has_attached_file :verification_documents
validates_attachment_content_type :verification_documents,
{ :content_type => %w( application/pdf ) }
end
Is it possible to update something like below in RegistrationsController as ?
# RegistrationsController < Devise::RegistrationsController
def update
if #user.update(user_params)
if params[:verification_documents]
params[:verification_documents].each do |doc|
#user.verification_documents.create(verification_documents: doc)
end
end
redirect_to root_path, notice: "Updated..."
else
render :edit
end
end
In application_controller.rb I have,
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up,
keys: [:fullname, :subscribe])
devise_parameter_sanitizer.permit(:account_update,
keys: [:fullname, :reset_password_token, :verification_documents])
end
Any Help is Highly Appreciated.Thanks in Advance!
UPDATE 1
I have added this to the Registrations Controller
def update
super
#user = User.find(current_user.id)
if params[:user][:verification_documents]
params[:user][:verification_documents].each do |doc|
#user.verification_documents.create(verification_documents: doc)
end
puts "document saved"
else
puts "not saved"
end
end
I tried to change the user phone number and upload the verification_documents (pdf's) in the users edit page.The values of devise user model Attribute's were successfully updated(The phone number is an attribute of user model).But the values for the verification_document model attributes are not saved.
phone number is updated but the verification_documents were still not saved
Log:
Processing by RegistrationsController#update as HTML
Parameters: {"utf8"=>"▒~\~S", "authenticity_token"=>"Xic+IFWWdzK4KaFzgnVzsOjMDPDaznJBjosj69khn3AfhrJr0mWsJrobK/mWHWiaANFqQAKj7wUPRYslfJZoPw==", "user"=>{"fullname"=>"Mohan Krishna Gangarapu", "email"=>"mohankrish93#gmail.com", "alternate_email"=>"", "business_name"=>"", "location"=>"", "phone_number"=>"9999999999", "alternate_phone_number"=>"", "dealer"=>"0", "fleet_manager"=>"0", "description"=>"", "url"=>"", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "deactivate"=>"false"}, "verification_documents"=>[#<ActionDispatch::Http::UploadedFile:0x007f1412365420 #tempfile=#<Tempfile:/tmp/RackMultipart20170411-23997-11lrzwz.pdf>, #original_filename="pdf-test.pdf", #content_type="application/pdf", #headers="Content-Disposition: form-data; name=\"verification_documents[]\"; filename=\"pdf-test.pdf\"\r\nContent-Type: application/pdf\r\n">, #<ActionDispatch::Http::UploadedFile:0x007f14123653f8 #tempfile=#<Tempfile:/tmp/RackMultipart20170411-23997-e1grsp.pdf>, #original_filename="pdfurl-guide.pdf.pdf", #content_type="application/pdf", #headers="Content-Disposition: form-data; name=\"verification_documents[]\"; filename=\"pdfurl-guide.pdf.pdf\"\r\nContent-Type: application/pdf\r\n">], "button"=>""}
^[[1m^[[36mUser Load (0.2ms)^[[0m ^[[1mSELECT `users`.* FROM `users` WHERE `users`.`id` = ? ORDER BY `users`.`id` ASC LIMIT 1^[[0m [["id", 686]]
^[[1m^[[35mUser Load (0.4ms)^[[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = ? LIMIT 1 [["id", 686]]
Unpermitted parameters: business_name, location
^[[1m^[[36mSQL (0.1ms)^[[0m ^[[1mBEGIN^[[0m
^[[1m^[[35mSQL (0.3ms)^[[0m UPDATE `users` SET `phone_number` = ?, `deactivate` = ?, `updated_at` = ? WHERE `users`.`id` = ? [["phone_number", "9999999999"], ["deactivate", 0], ["updated_at", "2017-04-11 05:32:57"], ["id", 686]]
^[[1m^[[36m (1.8ms)^[[0m ^[[1mCOMMIT^[[0m
Redirected to http://104.251.212.100:3000/
Completed 302 Found in 17ms (ActiveRecord: 3.6ms)
Started GET "/" for 156.73.67.6 at 2017-04-11 05:32:57 -0500
Cannot render console from 156.73.67.6! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by PagesController#home as HTML

Rails not updating attribute

Pretty standard update in my opinion, but upon submitting the put request, the attribute is not updated. Here is my relevant model:
class Vendor < ActiveRecord::Base
geocoded_by :address
after_validation :geocode,
:if => lambda{ |obj| obj.address_changed? }
end
My controller methods:
def edit
#vendor = Vendor.find(params[:id])
end
def update
#vendor = Vendor.find(params[:id])
if #vendor.update_attributes(vendor_params)
redirect_to vendors_mgmt_path
else
render 'edit'
end
end
def vendor_params
params.permit(:id, :name, :address, :image, :latitude, :longituded )
end
I see this in the server log after trying to update:
Started PUT "/vendors/1" for 127.0.0.1 at 2013-10-20 20:44:54 -0700
Processing by VendorsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"fTbZVEfckQz4xQzY5xSMQCArrGZqymNsVeyic/PXKcE=", "vendor"=>{"name"=>"Store", "address"=>"1221 E. Main St."}, "commit"=>"Save changes", "id"=>"1"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
Vendor Load (0.2ms) SELECT "vendors".* FROM "vendors" WHERE "vendors"."id" = ? LIMIT 1 [["id", "1"]]
Unpermitted parameters: utf8, _method, authenticity_token, vendor, commit
(0.1ms) begin transaction
(0.1ms) commit transaction
Redirected to http://localhost:3000/vendors/mgmt
Completed 302 Found in 10ms (ActiveRecord: 0.6ms)
This confuses me, because the Vendor form looks like so, and has no authenticity token etc.
<h1>Update <%= "#{#vendor.name}" %></h1>
<%= form_for(#vendor) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :Logo %>
<%= f.file_field :image %>
<%= f.submit "Save changes", class: "btn btn-success" %>
<% end %>
Anyone see any glaring errors? Any help is much appreciated. Thanks in advance!
Rails by default includes certain hidden fields in all forms, such as the authenticity_token, which is present to stop CSRF. (More info here) I would recommend changing the line:
params.permit(:id, :name, :address, :image, :latitude, :longituded )
to:
params.require(:vendor).permit(:id, :name, :address, :image, :latitude, :longituded)
Changing this line in your controller should permit the other parameters that are submitted by the form, not just the ones in the vendor param.
Also, you misspelled "longitude", I'm not sure if that's causing any additional trouble or if it's just a typo in your question instead.

What does AssociationTypeMismatch mean in ruby on rails? i'm getting this error with nested attributes

I have a system setup where users can post microposts (basically status updates) and upload a photo to go with the micropost.
I have:
Micropost model (has_one photo)
Photo_album model (has_many photos)
Photo model (belongs_to micropost, belongs_to photo_album)
User fills in text in text area and selects a photo. Upon submission the microposts table is updated with micropost related data such as content, created_at etc.
At the same time I want my photos table (Photo model) updated with the photo selection the user made but the correct photo album. If you look below you can see in my users_controller the instance variable #photo's value. This insures that the photo uploaded is linked to the correct photo album which is named "microposts album". It's purpose is to link up to all micropost related photos.
I have a Users_controller:
def new
#user = User.new
#micropost = Micropost.new(:user_id => users_id)
#photo = Photo.new(:photo_album_id => PhotoAlbum.where(:user_id => current_user.id, :album_title => "microposts album").first.id)
end
From a previous question I asked it was established I needed to use accepts_nested_attributes_for, fields_for in order to be able to update more than one model with one form. This is how I've set things up.
Micropost model:
class Micropost < ActiveRecord::Base
belongs_to :user
has_one :photo
accepts_nested_attributes_for :photo
attr_accessible :content, :user_id, :poster_id, :username, :image, :remote_image_url
end
Photo model:
class Photo < ActiveRecord::Base
belongs_to :photo_album
attr_accessible :photo_album_id, :photo_title, :image, :remote_image_url
mount_uploader :image, ImageUploader
end
Finally here is the micropost form:
= form_for #micropost, :remote => true do |f|
= f.fields_for #photo do |p|
= p.file_field :image
= f.hidden_field :user_id
= f.text_area :content
= f.submit "Post"
At first I got the error:
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: photo):
I was slightly confused because I thought the attributes were assigned automatically. At lesast thats what I read in the docs anyway. Anyway I went ahead and added :photo to the micropost model attr_accessible white list.
That first error went then I got this one:
ActiveRecord::AssociationTypeMismatch (Photo(#2169424320) expected, got ActiveSupport::HashWithIndifferentAccess(#2157396720)):
Maybe I've misunderstood how this feature works but I've read through this and also looked at the 3.2.3 api doc but not where I'm going wrong.
I would really appreciate some help with getting this to work.
Thanks in advance and I hope the long post was off putting. Just thought providing all this info would make people understand what I'm trying to do better.
Kind regards
Update:
Using :photo_attributes instead of photos gives me the following error:
Started POST "/microposts" for 127.0.0.1 at 2012-05-10 21:01:11 +0100
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] Processing by MicropostsController#create as JS
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] Parameters: {"micropost"=>{"photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00000102c293d8 #original_filename="7seriesbmw.jpeg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"micropost[photo][image]\"; filename=\"7seriesbmw.jpeg\"\r\nContent-Type: image/jpeg\r\n", #tempfile=#<File:/var/folders/fh/fhADKPjGG8qSuCeoHCTNYE+++TI/-Tmp-/RackMultipart20120510-14787-1e1mrhh>>}, "user_id"=>"2", "content"=>"ioo"}, "commit"=>"Post", "utf8"=>"✓", "authenticity_token"=>"/y8Lr+e7xgabt60GWxnMGvCtIi7IjqrYDoA84vAqYcE=", "remotipart_submitted"=>"true", "X-Requested-With"=>"IFrame", "X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"}
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1] Completed 500 Internal Server Error in 649ms
[02b23327ad83000f75c418d8739e7f49] [127.0.0.1]
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: photo):
app/controllers/microposts_controller.rb:9:in `create'
After changing the attr_accessor back to :photo instead of :photo_attributes:
Started POST "/microposts" for 127.0.0.1 at 2012-05-10 21:20:07 +0100
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] Processing by MicropostsController#create as JS
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] Parameters: {"micropost"=>{"photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00000102f8a3b0 #original_filename="7seriesbmw.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"micropost[photo][image]\"; filename=\"7seriesbmw.png\"\r\nContent-Type: image/png\r\n", #tempfile=#<File:/var/folders/fh/fhADKPjGG8qSuCeoHCTNYE+++TI/-Tmp-/RackMultipart20120510-15197-9rt2xn>>}, "user_id"=>"2", "content"=>"pp"}, "commit"=>"Post", "utf8"=>"✓", "authenticity_token"=>"/y8Lr+e7xgabt60GWxnMGvCtIi7IjqrYDoA84vAqYcE=", "remotipart_submitted"=>"true", "X-Requested-With"=>"IFrame", "X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"}
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1] Completed 500 Internal Server Error in 452ms
[985e0f204bf7ffac1f7c02fbec35ad9b] [127.0.0.1]
ActiveRecord::AssociationTypeMismatch (Photo(#2180069640) expected, got ActiveSupport::HashWithIndifferentAccess(#2153916820)):
app/controllers/microposts_controller.rb:9:in `create'
Microposts controller create action:
def create
if params[:micropost][:user_id].to_i == current_user.id
#micropost = current_user.microposts.build(params[:micropost])
#comment = Comment.new(:user_id => current_user.id)
respond_to do |format|
if #micropost.save
format.js { render :post_on_springboard }
end
end
else
user = User.find_by_username(params[:micropost][:username])
#micropost = user.microposts.build(params[:micropost])
if #micropost.save
UserMailer.new_wall_post_notification(user, current_user).deliver if user.email_notification == 1
flash[:success] = "Micropost posted"
redirect_to root_path+user.username
else
flash[:error] = "#{#micropost.errors.full_messages.first}"
redirect_to root_path+user.username
end
end
end
A lot of what you are trying to do concerns relationships and you shuld be able to get rails conventions working for you. If you start writing a bunch of code for somehting fairly simple with rails that's usually a bad sign.
I would focus first on your routes actually.
If you nest photo inside albums for instance, e.g.
resources :albums do
resources :photos
end
Then you will get a lot of the paths and functionality that you want.
Make sure your forms use things like form_for [#album, #post] which will go along with your accepts_nested_attributes_for
try adding :photo_attributes to your attar_accessible list in your micropost model
That should resolve the first error, I think.
Still looking into the second.
Can you post the complete stack trace from the form, it might be an issue with your controller mothods.
changing
f.fields_for #photo
to
f.fields_for :photo
and adding
#micropost.build_photo(:photo_album_id => :photo_album_id => current_user.photo_albums.find_by_album_title("microposts album").id)
to my microposts_controller fixed my issue
class Organization < ActiveRecord::Base
has_one :picture, :dependent => :destroy
accepts_nested_attributes_for :picture
attr_accessible :address, :contect_number, :email, :name, :type_of_organization, :picture_attributes
end
class Picture < ActiveRecord::Base
belongs_to :organization
mount_uploader :avatar, AvatarUploader
attr_accessible :avatar, :organization_id
end
class OrganizationsController < ApplicationController
load_and_authorize_resource
def new
#organization = Organization.new
# #organization.attributes = Picture.new
# #picture = Picture.new
end
def create
logger.info "++++++++inside the organisation controller++++++++++"
logger.info params[:organization].inspect
#org = Organization.new(params[:organization])
if #org.save
#picture = Picture.new(:avatar => params[:organization][:picture_attributes][:avatar])
#picture.organization_id = #org.id
#picture.save
logger.info "---------- inside Avtar controller ---------------"
logger.info #picture.inspect
session[:org_id] = #org.id
redirect_to new_admin_user_path :notice => 'Organization created successfully.'
else
render 'new'
end
end
end
<div>
<h4>FillUp organization details.</h4>
<%= form_for #organization, :url => organizations_path do |f| %>
<%= f.label :name, "Name" %>
<%= f.text_field :name %>
<%= f.label :contect_number, "Contact Number" %>
<%= f.text_field :contect_number %>
<%= f.label :address, "Address" %>
<%= f.text_field :address %>
<%= f.label :website, "Website" %>
<%= f.text_field :email %>
<%= f.label :company_type, "Type" %>
<%= f.text_field :type_of_organization %>
<%= f.fields_for :picture_attributes, :html => { :multipart => true } do |p| %>
<%= p.label :avatar, "My Avatar" %>
<%= p.file_field :avatar %><br/>
<%end%>
<%= f.submit :Create, :class => 'btn btn-primary' %>
<%end%>
</div>

Resources