Rails 4 Paperclip 3.5.1 missing image - ruby-on-rails

I have a Rails 4 application and just installed the Paperclip gem to handle image uploading. I can't get it working, after I've uploaded a photo it just says missing.
Someone has a clue what's going wrong?
~settings/_form.html.erb
> <%= form_for(#setting, :html => { :multipart => true }) do |f| %>
> <% if #setting.errors.any? %>
> <div id="error_explanation">
> <h2><%= pluralize(#setting.errors.count, "error") %> prohibited this setting from being saved:</h2>
>
> <ul>
> <% #setting.errors.full_messages.each do |msg| %>
> <li><%= msg %></li>
> <% end %>
> </ul>
> </div>
> <% end %>
>
> <div class="field">
> <%= f.label :title %><br>
> <%= f.text_field :title %>
> </div>
> <div class="field">
> <%= f.label :description %><br>
> <%= f.text_area :description %>
> </div>
> <div class="field">
> <%= f.label :paragraph %><br>
> <%= f.text_area :paragraph %>
> </div>
> <div>
> <%= f.file_field :photo %>
> </div>
> <div class="actions">
> <%= f.submit %>
> </div>
> <% end %>
My setting model ~setting.rb
class Setting < ActiveRecord::Base
attr_accessible :title, :description, :paragraph
has_attached_file :photo
end
Photo Migration
class AddAttachmentPhotoToSettings < ActiveRecord::Migration
def self.up
change_table :settings do |t|
t.attachment :photo
end
end
def self.down
drop_attached_file :settings, :photo
end
end
Setting migration
class CreateSettings < ActiveRecord::Migration
def change
create_table :settings do |t|
t.string :title
t.text :description
t.text :paragraph
t.timestamps
end
end
end
~settings/Show.html.erb
<p id="notice"><%= notice %></p>
<p> <%= image_tag #setting.photo.url %> </p> <br />
<p>
<strong>Title:</strong>
<%= #setting.title %>
</p>
<p>
<strong>Description:</strong>
<%= #setting.description %>
</p>
<p>
<strong>Paragraph:</strong>
<%= #setting.paragraph %>
</p>
<%= link_to 'Edit', edit_setting_path(#setting) %> |
<%= link_to 'Back', settings_path %>
Can't figure out what's wrong. The uploaded photo does'nt show it just says "Missing". Would appreciate some help! :)

You can keep the first one : setting_params. It seems to be a method in your controller to ensure strong parameters (see: http://guides.rubyonrails.org/getting_started.html#saving-data-in-the-controller).
To resolve it, add the relation in this method like this :
private
def setting_params
params.require(:post).permit(:title, :description, :paragraph, :photo)
end

I'm glad to tell everyone that have or will have the same problem that I just figured it out!
By default your generated controller that you want to add the :photo attribute to defines "create" like this:
def create
#setting = Setting.new(setting_params)
end
Just cange it to:
def create
#setting = Setting.create(params[:setting])
end
(Just to be clear; Change setting to your own scaffold name.)

Related

Rails: Changing name for a button

I'm creating a database website using rails. I implemented where a user can upload an image. There are two places where you can upload an image, one for a vendor and other for the inventory. One of the model is called "photos" and the other "fotos". I'm new to rails and wasn't sure how to use the same model, "photos" to upload to the other part of the database, so I created the model "foto" and followed the tutorial. But now when you upload a photo, the button says "Create Foto". I want it to say "Create Photo". I'm not sure how to do this.
Some of my code files
_form.html.erb/fotos/view
<%= form_for([#vendor, #vendor.fotos.build]) do |f| %>
<div class="form-group1">
<%= f.label :image %>
<%= f.file_field :image, class: 'form-control1'%>
</div>
<p>
<%= f.submit %>
</p>
<% end %>
_foto.html.erb/fotos/view
<div class="media1">
<div class="media-left1">
<%= link_to image_tag(foto.image.url, class: 'media-object1'), foto.image.url, target: '_blank' %>
</div>
<div class="media-body1">
<h4 class="media-heading1"><%= foto.title %></h4>
</div>
</div>
<p>
<%= link_to 'Delete Photo', [foto.vendor, foto],
method: :delete,
data: { confirm: 'Are you sure?' } %>
</p>
show.html.erb/vendors/view
<body>
<div class = "head">
<h1>Vendor Information</h1>
<div class = "image1" >
<img src= "http://dx.deucex.com/i/logo.png" >
</div>
</div>
</body>
<%= render #vendor.fotos %>
<h3>Add a photo:</h3>
<%= render 'fotos/form' %>
<p>
<strong>Company:</strong>
<%= #vendor.company %>
</p>
<p>
<strong>Contact Name:</strong>
<%= #vendor.contact_name %>
</p>
<p>
<strong>Phone:</strong>
<%= #vendor.phone %>
</p>
<p>
<strong>Email:</strong>
<%= #vendor.email %>
</p>
<p>
<strong>MOQ:</strong>
<%= #vendor.moq %>
</p>
<p>
<strong>Cost/Item:</strong>
<%= #vendor.cost_per_item %>
</p>
<p>
<strong>Payment Method:</strong>
<%= #vendor.payment_method %>
</p>
<p>
<strong>Terms:</strong>
<%= #vendor.terms %>
</p>
<p>
<strong>Turnover Period:</strong>
<%= #vendor.turnover %>
</p>
<p>
<strong>Returns:</strong>
<%= #vendor.returns %>
</p>
<p>
<strong>Notes:</strong>
<%= #vendor.notes %>
</p>
<%= link_to 'Back', vendors_path %>
fotos_controller.rb
class FotosController < ApplicationController
def index
#fotos = Foto.order('created_at')
end
def new
#foto = Foto.new
end
def create
#vendor = Vendor.find(params[:vendor_id])
#foto = #vendor.fotos.create(photo_params)
redirect_to vendor_path(#vendor)
end
def destroy
#vendor = Vendor.find(params[:vendor_id])
#foto = #vendor.fotos.find(params[:id])
#foto.destroy
redirect_to vendor_path(#vendor)
end
private
def photo_params
params.require(:foto).permit(:title, :image)
end
end
foto.rb/model
class Foto < ApplicationRecord
has_attached_file :image
belongs_to :vendor
validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/
end
migration file
class CreateFotos < ActiveRecord::Migration[5.1]
def change
create_table :fotos do |t|
t.string :title
t.references :vendor, foreign_key: true
t.timestamps
end
end
end
another migration file
class AddAttachmentImageToFotos < ActiveRecord::Migration[5.1]
def self.up
change_table :fotos do |t|
t.attachment :image
end
end
def self.down
remove_attachment :fotos, :image
end
end
<%= f.submit 'Create Photo' %>
This should rename the button. For more options use the following link
https://apidock.com/rails/ActionView/Helpers/FormBuilder/submit
There are two ways.
1. Pass a value to submit_tag
<%= f.submit 'Create Photo' %>
2. Use the I18N module
# config/locales/en.yml
en:
helpers:
submit:
foto:
create: "Create Photo"
This approach is better if you at some point intend to translate the application. It also makes it easy to use the same form for create and update and have the correct text for each.

Rails 4: replace / delete uploaded file in edit view form

A similar question has already been asked, but the answer is only for Rails 3, so I am taking the liberty of asking a new question.
I have a Rails 4 app, with the following models:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many: :posts
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
The Post model has the following attributes:
references :calendar, index: true, foreign_key: true
date :date
time :time
string :subject
string :format
text :copy
attachment :image
and the attachment was setup as follows with Paperclip in Post model:
has_attached_file :image, styles: { small: "64x64", med: "100x100", large: "200x200" }
validates_attachment :image, :content_type => { :content_type => "image/png" },
:size => { :in => 0..3000.kilobytes }
Adding an image to a Post is working fine, through the following form:
<%= form_for [#calendar, #calendar.posts.build] do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<p>
<%= f.label :date %><br>
<%= f.date_select :date %>
</p>
<p>
<%= f.label :time %><br>
<%= f.time_select :time %>
</p>
<p>
<%= f.label :subject %><br>
<%= f.text_field :subject %>
</p>
<p>
<%= f.label :format %><br>
<%= f.text_field :format %>
</p>
<p>
<%= f.label :copy %><br>
<%= f.text_area :copy %>
</p>
<p>
<%= f.label :image %><br>
<%= f.file_field :image %>
</p>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Viewing the image attached to a Post is also working well, thanks to this show view:
<h2>Post from <%= #post.date.strftime("%A, %d") %></h2>
<div>
<p><strong>Date</strong></p>
<%= #post.date.strftime("%A, %d") %>
</div>
<div>
<p><strong>Time</strong></p>
<%= #post.time.strftime("%I:%M %p") %>
</div>
<div>
<p><strong>Subject</strong></p>
<%= #post.subject %>
</div>
<div>
<p><strong>Format</strong></p>
<%= #post.format %>
</div>
<div>
<p><strong>Copy</strong></p>
<%= #post.copy %>
</div>
<div>
<p><strong>Image</strong></p>
<%= image_tag #post.image.url(:med) %>
</div>
However, when I go to the edit view, for a post where I have previously uploaded an image, I only see the field that allows me to add an image and a message saying "no file chosen".
The edit view uses (for now) the same form as the new view, as shown above.
How can I achieve the following:
Have the uploaded image appear in the edit page.
Allow users to delete this image.
Allow users to replace this image with a new one.
–––––
UPDATE: I found a way to solve item #1 above, by replacing
<p>
<%= f.label :image %><br>
<%= f.file_field :image %>
</p>
with
<p>
<%= f.label :image %><br>
<% if #post.image.exists? %>
<%= image_tag #post.image.url(:med) %>
<% else %>
<%= f.file_field :image %>
<% end %>
</p>
in my Post edit view.
I am still working on items #2 & #3 and could definitely use some help with these.
–––––
I am happy to share more code if necessary.
Any idea?
For #2 - Allow user to delete image, you might find this SO Issue helpful
OR, as per Paperclip's documentation you could simply create a dummy checkbox and, in the update method of your controller, look if the checkbox has been ticked and delete the attachment as mentioned in the documentation.
For #3 - Allow users to replace this image with a new one
Simply rework your code as follow:
<p>
<%= f.label :image %><br>
<% if #post.image.exists? %>
<%= image_tag #post.image.url(:med) %>
<% end %>
<%= f.file_field :image %>
</p>
This way, the file_field is always present (allowing user to replace or add their image)

How to save nested form data in Rails?

I have this data inside my foods and drinks table:
Foods table
ID | Name
------------
1 | Rojak
2 | Lemang
Drinks table
ID | Name
------------
1 | Barli
2 | Sirap
My model relationship is:
class Survey < ActiveRecord::Base
has_many :questions
accepts_nested_attributes_for :questions, allow_destroy: true
end
class Question < ActiveRecord::Base
belongs_to :survey
has_many :answers
accepts_nested_attributes_for :answers, allow_destroy: true
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :foods
has_many :drinks
accepts_nested_attributes_for :foods, :drinks
end
class Food < ActiveRecord::Base
belongs_to :answer
end
class Drink < ActiveRecord::Base
belongs_to :answer
end
And this is my _form.html.erb file inside app/views/surveys:
<%= form_for #survey do |f| %>
<% if #survey.errors.any? %>
<div class="error_messages">
<h2><%= pluralize(#survey.errors.count, "error") %> prohibited this survey from being saved:</h2>
<ul>
<% #survey.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<br>
<%= f.fields_for :questions do |f| %>
<fieldset>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content %><br />
<% Food.all.each do |fd| %>
<fieldset>
<%= f.fields_for :answers do |f| %>
<%= f.text_field :name, :value => fd.name %>
<%= f.number_field :quantity %>
<% end %> <br>
</fieldset>
<% end %>
</fieldset>
<br>
<% end %>
<br>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I'm trying to do is:
List all foods name and drinks name inside foods and drinks fieldset
Give each of the foods and drinks a quantity (this quantity column is inside answers table)
Save and update it
But I got no luck. When I'm try to load the edit view (the form), I managed to list all of the foods name. But, I've no idea how to list all of the drinks name in its own fieldset.
I try to make it like this but it didn't work:
<% if :content == "Foods" %>
<%= #loads foods %>
<% else %>
<%= #loads drinks %>
<% end %>
And, when I try to save the foods/drinks name and its quantity, it didn't work too.
Demo:
How to fix this problem?
Note:
This is update method inside surveys_controller:
def update
if #survey.update(survey_params)
redirect_to #survey, notice: "Successfully updated survey."
else
render :edit
end
end
...
def survey_params
params.require(:survey).permit(:name, questions_attributes: [:id, :_destroy, :content, answers_attributes: [:id, :_destroy, :content, :quantity]])
end
Update:
This is my show.html.erb
<h1><%= #survey.name %></h1>
<ul class="questions">
<% #survey.questions.each do |question| %>
<li>
<%= question.content %>
<ol class="answers">
<% question.answers.each do |answer| %>
<li><%= answer.content %> (<%= answer.quantity %>)</li>
<% end %>
</ol>
</li> <br>
<% end %>
</ul>
<%= link_to 'Edit', edit_survey_path(#survey) %> |
<%= link_to 'Back to Surveys', surveys_path %>
You might be seeing an issue with variable scope. Each time you create a nested form with f.fields_for you pass in the variable f, even though f is the variable used in the parent.
Try calling it something different with questions and answers, such as:
<%= f.fields_for :questions do |fq| %>
<fieldset>
<%= fq.label :content, "Question" %><br />
<%= fq.text_area :content %><br />
<% Food.all.each do |fd| %>
<fieldset>
<%= fq.fields_for :answers do |fa| %>
<%= fa.text_field :name, :value => fd.name %>
<%= fa.number_field :quantity %>
<% end %> <br>
</fieldset>
<% end %>
</fieldset>
<br>
<% end %>

How to save form values in database using ROR

Can anybody help me to save these form values in database.I have already created one form.When I clicked on submit button the below validation message is coming.
1 error prohibited this post from being saved:
Gender must be accepted
Please check the code and help me to save all values in DB.If any error found please make it correct.
My code is as follows:
views/students/index.html.erb
<h1>Choose the option</h1>
<p>
<%= link_to "Enter student data",students_new_path %>
</p>
<p>
<%= link_to "Display your data",students_show_path %>
</p>
views/students/new.html.erb
<h1>Enter your data</h1>
<%= form_for #student,:url => {:action => 'create'} do |f| %>
<% if #student.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#student.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #student.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<label for="name">Name:</label>
<%= f.text_field :name,placeholder:"Enter your name" %>
</p>
<p>
<label for="gender">Gender:</label><br>
<%= f.radio_button :gender,'Male',:checked => true %>
<%= f.label :Male %>
<%= f.radio_button :gender,'Female' %>
<%= f.label :Female %>
</p>
<p>
<label for="city">Select the City</label>
<%= f.select(:city,options_for_select([['Bhubaneswar','Bhubaneswar'],['Cuttack','Cuttack'],['Behrempur','Behrempur'],['Puri','Puri']],selected: "Puri")) %>
</p>
<p>
<%= f.check_box :terms_service %> accept terms and service
</p>
<p>
<%= f.submit "Submit" %>
</p>
<% end %>
controller/students_controller.rb
class StudentsController < ApplicationController
def index
end
def show
end
def new
#student=Student.new
end
def create
#student=Student.new(users_params)
if #student.save
flash[:notice]="You have signed up successfully.."
flash[:color]="valid"
redirect_to :action => 'index'
else
flash[:notice]="You have not signed up successfully"
flash[:color]="invalid"
render :new
end
end
private
def users_params
params.require(:student).permit(:name,:gender,:city,:terms_service)
end
end
model/student.rb
class Student < ActiveRecord::Base
validates :name ,:presence => true,:length => { :minimum => 6 }
validates :gender, :acceptance => true
validates :terms_service, :acceptance => true
end
migrate\20150114061737_create_students.rb
class CreateStudents < ActiveRecord::Migration
def change
create_table :students do |t|
t.string :name
t.string :gender
t.string :city
t.string :terms_service
t.timestamps null: false
end
end
end
Please help me to run this code successfully.Thanks in advance..
Validation type used for gender field is wrong ie acceptance validation is used when you want to check if a check-box is checked by user in the form. In your situation you should use
validates :gender, :presence => true

Nested Attributes in Form Not showing

I have the 3 Models, that says a Voter has many votes and i'm trying to get the voter to vote on the same form as when the voting object is created but the field in my form isn't showing.
Here are my models:
class Voter < ActiveRecord::Base
attr_accessible :email_address, :verification_code, :verified, :votes_attributes
has_many :votes, :class_name => "Vote"
accepts_nested_attributes_for :votes
end
class Vote < ActiveRecord::Base
belongs_to :entry
belongs_to :voter
attr_accessible :entry, :voter, :voter_id
end
And in my form I have:
<%= form_for(#voter) do |f| %>
<% if #voter.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#voter.errors.count, "error") %> prohibited this voter from being saved:</h2>
<ul>
<% #voter.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email_address %><br />
<%= f.text_field :email_address %>
</div>
<div class="field">
<%= f.label :verification_code %><br />
<%= f.text_field :verification_code %>
</div>
<div class="field">
<%= f.label :verified %><br />
<%= f.check_box :verified %>
</div>
<div class="field">
<% f.fields_for :votes do |builder| %>
<fieldset>
<%= builder.label :votes, "Entry" %>
<%= collection_select(:entry, :entry_id, Entry.all, :id, :email_address, :prompt => 'Please select an Entry') %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
But the votes field isn't showing. And I can't understand why.
In rails 3 you need to use:
<%= f.fields_for :votes do |builder| %>
This will fix the problem.

Resources