Post model missing required attr_accessor for 'image_file_name' - ruby-on-rails

i just started to do a sample webpage in ruby on rails.
i am getting an error "Post model missing required attr_accessor for 'image_file_name'" when i tried to post the image from a form.
my code is
routes.rb
Rails.application.routes.draw do
resources :posts
root 'posts#index'
end
posts_controll.rb
class PostsController < ApplicationController
def index
end
def new
#post = Post.new
end
def create
#post = Post.create(post_params)
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:image, :caption)
end
end
newhtml.erb
<%= simple_form_for #post do |f| %>
<%= f.input :image %>
<%= f.input :caption %>
<%= f.button :submit %>
<% end %>
post.rb
class Post < ActiveRecord::Base
validates :image, presence: true
has_attached_file :image, styles: { :medium => "640x" }
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end
i didnt understand the error here. i think i have done all right.
please help me guys .

Related

Model returns no data ruby on rails

Im following this tutorial: https://www.devwalks.com/lets-build-instagram-in-rails-part-1/
To create a version of instagram. When I upload an image, add a caption and submit, it will redirect to the index page as expected but the data doesnt seem to have been saved. When I open the rails console and try to get the posts with Posts.first, it returns nil.
Controller:
class PostsController < ApplicationController
def index
end
def new
#post = Post.new
end
def create
#post =Post.create(post_params)
#post.save
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:image, :caption)
end
end
Model:
class Post < ActiveRecord::Base
validates :image, presence: true
has_attached_file :image, styles: { :medium => "640x"}
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end
form:
<%= simple_form_for #post do |f| %>
<%= f.input :image %>
<%= f.input :caption %>
<%= f.button :submit %>
<% end %>
routes:
resources :posts
root 'posts#index'
Appreciate any ideas.
Thanks
I see a few problems here:
create will save so you don't need another #post.save.
create returns the new Post object, but you have to check if it has been saved successfully or not (via #post.persisted, or via if #post.save).
From 1 & 2, I believe your post was not saved, due to validation on image presence.
Now why it's happening? I guess your form has no multipart/form-data set that the image file was not submitted at all.
To add that to simple_form (paperclip README) :
<%= simple_form_for #post, html: { multipart: true } do |f| %>

Nested models with simple_form and paperclip

[This maybe a simple issue, but I just can't find a solution]
I'm trying to update an existing record with new data and add some image(s) to that record (via paperclip), however, my code doesn't show the paperclip field at all.
I've followed this example and also tried with this solutions, but nothing works.
I have two, models Hotel and HotelImage.
hotel.rb
class Hotel < ActiveRecord::Base
extend FriendlyId
friendly_id :slug_candidates, use: :slugged
validates :name, presence: true
validates :location, presence: true
has_many :hotel_images
accepts_nested_attributes_for :hotel_images
def slug_candidates
[
[:name, :location],
]
end
end
hotel_image.rb
class HotelImage < ActiveRecord::Base
belongs_to :hotel
#rails generate paperclip hotel_image image
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
edit.html.erb
<%= simple_form_for #hotel, :url => admin_hotel_path, method: :put, html: { multipart: true } do |f| %>
<%= f.error_notification %>
<%= f.input :name %>
<%= f.input :location %>
<%= f.simple_fields_for :hotel_images do |ff| %>
<%= ff.input :image, as: :file %>
<% end %>
<%= f.button :submit %>
<% end %>
hotels_controller.rb
#other code
def update
#hotel = Hotel.friendly.find(params[:slug])
if #hotel.update(hotel_params)
redirect_to admin_hotels_path, notice: 'Hotel was successfully updated.'
else
render :edit
end
end
private
def hotel_params
params.require(:hotel).permit(:name, :location, :admin_id, hotel_images_attributes: [:hotel_id, :image])
end
Here's the print screen of the form, where you can see that the paperclip field is missing:
However, when I change f.simple_fields_for :hotel_images to, for example, f.simple_fields_for :foobars, the paperclip field is shown:
Note: the name and location attributes update just fine.
def update
#hotel = Hotel.friendly.find(params[:slug])
if #hotel.update(hotel_params)
redirect_to admin_hotels_path, notice: 'Hotel was successfully updated.'
else
render :edit
end
end
def edit
#hotel_images = #hotel.hotel_images.present? ? #hotel.hotel_images : #hotel.hotel_images.build
end
Try this code

syntax error, unexpected '\n', expecting :: or '[' or '.'

I am trying to have an image uploader on my app using Paperclip, and my only problem is that I keep getting an Undefined Method error.
I have it set up on github, https://github.com/BBaughn1/savagelysaving
My User Controller:
class UserController < ApplicationController
def create
#user = User.create( user_params )
end
def destroy
#user.image = nil
#user.save
end
private
# Use strong_parameters for attribute whitelisting
# Be sure to update your create() and update() controller methods.
def user_params
params.require(:user).permit(:image)
end
end
Then my Show.html.erb file:
<div id="post_content">
<h1 class="title">
<%= #post.title %>
</h1>
<p class="date">
Submitted <%= time_ago_in_words(#post.created_at) %> Ago
<% if user_signed_in? %>
| <%= link_to 'Edit', edit_post_path(#post) %>
| <%= link_to "Delete", post_path(#post), method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
</p>
<p class="body">
<%= #post.body %>
<%= image_tag #post.image.url(:medium) %>
</p>
<div id="comments">
<%= render 'disqus' %>
</div>
</div>
In my post.rb file:
class Post < ActiveRecord::Base
has_many :comments, dependent: :destroy
validates :title, presence: true, length: { minimum: 5 }
validates :body, presence: true
attr_accessor :image
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100#" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
end
in my development.rb file:
Rails.application.configure do
***STUFF***
Paperclip.options[:command_path] = "/usr/local/bin/"
end
and posts controller:
class PostsController < ApplicationController
# before_action :find_post, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show]
def index
#posts = Post.all.order('created_at DESC')
end
def new
#post = Post.new
attr_accessor :image
end
def create
attr_accessor :image
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
attr_accessor :image
if #post.update(params[:post].permit(:title, :body, :image))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:title, :body, :image)
end
end
There is no avatar attribute in your user model but there is an image attribute in your post model.
If you remove below code from user model and move it to post model, the image upload will work
has_attached_file :image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/
This should fix the bug.
I looked at your github to see if you made the same mistake I did. I think you forgot to add imagemagick to your development.rb file. When you install imagemagick on your local machine, it need to see where it's installed; which convert where show where. It might look like this Paperclip.options[:command_path] = "/usr/local/bin/" if not, just copy what it show you and edit what's in the quotes " ".
I hope that helps I know I was having some trouble getting it to work.

Multiple images(Nested) not getting uploaded via paperclip in ruby on rails

I am developing a website in ruby on rails. I want to upload multiple images while creating post using paperclip. I could not find any images being uploaded into the public folder and hence images are not getting displayed when I create new post. I have created a model called Postimage.rb for images and referenced to already existing model "post".I have used paperclip to upload single image in other models and it is working fine.
rails g model postimage post:references caption:string
rails g paperclip post_images photo
Here is the Postimage.rb
class Postimage < ActiveRecord::Base
belongs_to :post
has_attached_file :photo,
:styles => {:small => "100x100>", :medium => "640x480>"}
validates_attachment_content_type :photo, :content_type => /\Aimage\/.*\Z/
end
And in the Post model,
class Post < ActiveRecord::Base
has_many :postimages
accepts_nested_attributes_for :postimages, :allow_destroy => true, :reject_if => lambda { |t| t[:postimage].nil? }
Here is the code in post controller
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#posts = Post.all.order('created_at DESC').paginate(page: params[:page],:per_page =>7)
#users = User.all
respond_with(#posts)
end
def show
respond_with(#post)
end
def new
#post = Post.new
5.times {#post.postimages.build} # added this
respond_with(#post)
end
def edit
5.times{#post.postimages.build} # ... and this
end
def create
#post = current_user.posts.build(post_params)
#post.user_id = current_user.id
if #post.save
redirect_to #post, :notice =>"Post created successfully!!"
else
render "new"
end
end
def update
#post.update(post_params)
respond_with(#post)
end
def destroy
#post.destroy
redirect_to preschools_Home_path
#respond_with(#post)
end
private
def set_post
#post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :content, postimages_attributes: [:caption, :photo])
end
Here is the code in _form.html in posts
<%= form_for(#post, :html =>{:multipart => true }) do |f| %>
<%=f.fields_for :postimages do |builder| %>
<%if builder.object.new_record? %>
<p>
<%= builder.label :caption, "Image Caption" %>
<%= builder.text_field :caption %>
</p>
<p>
<%= builder.label :photo, "Image File" %>
<%= builder.file_field :photo %>
</p>
<% end %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here is the code in show.html.erb in posts
<div>
<% #post.postimages.each do |postimage|%>
<%= image_tag (postimage.photo.url(:medium))%>
<% end %>
</div>
Can you please help me. Thanks.
I have added image column to post model. And that image is getting displayed. But in the case of multiple upload, it is not working.
Logs code below might help.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"PHcPmsB+a0qy6tn4U/nRyycjGFYHiFuum7LNqO8EX24+mGq+Yu7Ct0Ls/odNyAjUtVkT1cMImYRYwnpVajQRXA==", "post"=>{"title"=>"1st post", "content"=>"Added image", "postimages_attributes"=>{"0"=>{"caption"=>"1st image", "photo"=>#<ActionDispatch::Http::UploadedFile:0x007f4a351b0ba8 #tempfile=#<Tempfile:/home/ubuntu/workspace/website/RackMultipart20150715-1790-7hfszv.jpg>, #original_filename="Murali.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"post[postimages_attributes][0][photo]\"; filename=\"Murali.jpg\"\r\nContent-Type: image/jpeg\r\n">}
The solution provided below works with Paperclip as well:
Rails 4 multiple image or file upload using carrierwave
Only difference would be in post_attachment.rb
Instead of:
class PostAttachment < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
belongs_to :post
end
You would have
class PostAttachment < ActiveRecord::Base
belongs_to :post
has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/
end

Rails: Form doesn't add data to model

I have a form for creating a new :thing, with a collection_select field to enter an existing :thing the new :thing is related to. Each :thing has_many :things, through an intermediary model :related_things, which has a thing_a_id and thing_b_id. So when I fill in the field and click submit, a :related_thing is supposed to be created with thing_a_id and thing_b_id equal to the two thing_ids, respectively. But no such :related_thing is created; the form doesn't do anything. The other textfields do work though. What's wrong with my code?
I'm using Rails 4.0.10.
Things/new View:
<h1>Add Something!</h1>
<p>
<%= form_for #thing, :url => things_path, :html => { :multipart => true } do |f| %>
<%= f.text_field :name, :placeholder => "Name of the thing" %>
<br>
<%= f.label :related_things %>
<%= f.collection_select :related_things, Thing.all, :id, :name %>
<br>
<%= f.label :display_picture %>
<%= f.file_field :avatar %>
<br>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</p>
Thing Model:
class Thing < ActiveRecord::Base
has_many :related_things
has_many :things, :through => :related_things
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "30x30!" }, :default_url => "/images/:style/missing.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
def related_things
related_thing_ids = RelatedThing.
where("thing_a_id = ? OR thing_b_id = ?", self.id, self.id).
map { |r| [r.thing_a_id, r.thing_b_id] }.
flatten - [self.id]
Thing.where(id: related_thing_ids)
end
def related_thing_ids=(ids)
ids.each do |id|
record = RelatedThing.where(thing_a_id: self.id, thing_b_id: id).first
record ||= RelatedThing.where(thing_a_id: id, thing_b_id: self.id).first
record ||= RelatedThing.create!(thing_a_id: self.id, thing_b_id: id)
end
end
end
RelatedThing Model:
class RelatedThing < ActiveRecord::Base
has_many :things
end
Things Controller:
class ThingsController < ApplicationController
def show
#thing = Thing.find(params[:id])
#related_thing = RelatedThing.all
#thing.things.build
end
def new
#thing = Thing.new
#things = Thing.all
end
def create
#thing = Thing.new(thing_params)
if #thing.save
redirect_to #thing
else
render 'new'
end
end
private
def thing_params
params.require(:thing).permit(:name, :image_path, :avatar)
end
end
RelatedThings Controller:
class RelatedThingsController < ApplicationController
def new
#things = Thing.all.by_name
end
def create
#things = Thing.all.by_name
end
def edit
#things = Thing.all.by_name
end
end
There are two problems causing this:
As Jamesuriah pointed out, your collection_select should use the related_things_ids field instead.
Despite that change, the field is actually being filtered out of the parameter map because of Rails' Strong Parameters.
Specifically, in your controller, the thing_params method should look like:
def thing_params
params.require(:thing).permit(:name, :image_path, :avatar, :related_things_ids)
end
Read up on strong parameters in the link above for more info. Hope that helps!
The collection select should be named related_thing_ids for your model to work, I believe.

Resources