Rails carrierwave has_many error

26 views
Skip to first unread message

Bazley

unread,
Jul 9, 2015, 4:28:08 PM7/9/15
to rubyonra...@googlegroups.com
Each User has_one Character. Each Character has_one :profilepicture, of class Picturething, which holds a Carrierwave mount_uploader to upload a singe picture. Each Character has_many :standardpictures, also of class Picturething. Picture upload is handled in views/users/edit, which hits the update_pictures method in users_controller.

The idea is to upload one standardpicture at a time. It seems to work, Rails console > Picturething.all shows that a new Picturething has been added to the database, and it is correctly displayed on the page. This is intended to be one of the character.standardpictures.

The weird thing is, somehow in this whole process, the character's :profilepicture is also set to be the same picture that was uploaded. I don't understand how this is happening. At no point do I have code saying something like "@character.profilepicture = standardpicture", but somehow it has decided that both the first :standardpicture and the :profilepicture are one and the same. If the profilepicture exists, which it shouldn't yet, it is displayed on the edit.html.erb page, where I have the line `<% if @character.profilepicture.nil? %>`. It displays the uploaded picture here, so clearly profilepicture is not nil, but it should be.

How is this happening?

character.rb:

    has_many :standardpictures, class_name: "Picturething", dependent: :destroy
    accepts_nested_attributes_for
:standardpictures
    has_one  
:profilepicture, class_name: "Picturething", dependent: :destroy
    accepts_nested_attributes_for
:profilepicture

picturething.rb:

    class Picturething < ActiveRecord::Base
      belongs_to      
:character
      mount_uploader  
:picture, CharacterpicUploader
      validate        
:picture_size
   
end

app/views/users/edit.html.erb:

    <%= form_for :standardpicture, url: update_pictures_user_path,
                 method
: :post, html: { multipart: true } do |f| %>
     
<%= f.label :picture %>
     
<%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
     
<%= f.submit "Upload pictures", class: "btn btn-primary" %>
   
<% end %>

routes.rb:

    post '/users/:callsign/update_pictures', to: 'users#update_pictures',  as: :update_pictures_user

users_controller.rb:

    def update_pictures
     
@character = Character.find_by(callsign: params[:callsign])
     
@user = @character.sociable
     
@standardpicture = @character.standardpictures.build(update_pictures_user_params)
     
if @standardpicture.save
        flash
[:success] = "Pictures updated"
        redirect_to
(edit_user_path(@user))
     
else
        redirect_to
(edit_user_path(@user))
     
end
   
end # update_pictures

   
def update_pictures_user_params
     
params.require(:standardpicture).permit(:picture)
   
end

Back to app/views/users/edit.html.erb:

    <% if @character.profilepicture.nil? %>
     
<p>Select a picture below to use as your profile picture</p>
   
<% else %>
     
<%= image_tag @character.profilepicture.picture %>
   
<% end %>

Colin Law

unread,
Jul 9, 2015, 5:02:16 PM7/9/15
to rubyonra...@googlegroups.com
You need two belongs_to here, one for each association. Use unique
names, foreign_key and class_name here and in character.rb to specify
which is which. Then obviously two _id fields.

Currently it is conflating the two relationships.

Colin

Bazley

unread,
Jul 10, 2015, 12:34:24 PM7/10/15
to rubyonra...@googlegroups.com
Thank you Colin, that fixed it. I appreciate your help. 
The solution raises an interesting question, fully specified here on SO if you're interested:
 
http://stackoverflow.com/questions/31306347/rails-carrierwave-has-many-error/31345762#31345762

The question is, is a solution possible with only a single column in the Picturething model? Having two columns seems redundant when they are only ever going to hold the same value (the character_id)?

Thanks again!
 

Colin Law

unread,
Jul 10, 2015, 5:01:13 PM7/10/15
to rubyonra...@googlegroups.com
It is not redundant as which one it is in tells you which association
it is. You could have an entry in both. If you can't have an entry
in both then you many not have specified the associations in the best
way. Have just one association and use a different method of saying
which type it is for example.

Colin
Reply all
Reply to author
Forward
0 new messages