ArgumentError in SongsController#create missing required :bucket option - ruby-on-rails

I've been trying to get paperclip working with amazon s3 all day and I'm gettin' pretty close.
Albeit, how do I get around this error? I've included the bucket in the song model so I'm not sure what it's asking for. Once this is solved it should work.
Error:
ArgumentError in SongsController#create
missing required :bucket option
respond_to do |format|
if #song.save
format.html { redirect_to #song, notice: 'Song was successfully created.' }
format.json { render action: 'show', status: :created, location: #song }
else
song.rb
class Song < ActiveRecord::Base
acts_as_voteable
belongs_to :user
has_many :comments, :dependent => :destroy
has_many :genre_songs
has_many :genres, through: :genre_songs
has_attached_file :track,
:storage => :s3,
:path => '/:class/:attachment/:id_partition/:style/:filename',
:url => ":s3_domain_url",
:bucket => ENV['bucketname']
validates_attachment :track, :presence => true
validates_presence_of :url
validates :title, length: { minimum: 10 }
validates :url, length: { maximum: 300 }
def self.tagged_with(name)
Genre.find_by_name!(name).songs
end
def tag_list
genres.map(&:name).join(", ")
end
def tag_list=(names)
self.genres = names.split(",").map do |n|
Genre.where(name: n.strip).first_or_create!
end
end
end
paperclip.rb
# config/initializers/paperclip.rb
Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
production.rb and development.rb
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['my bucketname'],
:access_key_id => ENV['my access key'],
:secret_access_key => ENV['my secret access key']
}
}
show.html.erb
<p id="notice"><%= notice %>
<p>
<%= #song.title %> | ( <%= #song.url %> )
<br />
<span class="subtext"><span class="votes_<%= #song.id %>"><%= pluralize(#song.votes.count, 'like') %>,</span>
posted <%= time_ago_in_words(#song.created_at) + " ago" %>
<small><span class="comments"></small> | <%= pluralize(#song.comments.size, 'comment') %></span></small><br /></span></span>
</p>
<p>
<%= audio_tag (#song.track.url), controls: "controls", alt: "Please use chrome, ie, or safari", preload: :auto %>
</p>
<p>Genres: <%= raw #song.genres.map(&:name).map { |t| link_to t, genre_path(t) }.join(', ') %></p>
<%#= link_to 'Show', song, class: "button small secondary" %>
<%= link_to('Edit', edit_song_path(#song), class: "button small secondary") if can? :update, #song %>
<%#= link_to 'Back', songs_path, class: "button small secondary" %>
<br /><br />
<%= render :partial => 'comments/form' %>
<div class="replies">
<% unless #song.comments.empty? %>
<h5><%= pluralize(#song.comments.size, 'comment') %></h5>
<br />
<% end %>
<% if #song.comments.empty? %>
<p>There are no comments...</p>
<% else %>
<div id="comments">
<% for comment in #song.comments %>
<div class="comment">
<strong><%= link_to_unless comment.site_url.blank?, h(comment.author_name), h(comment.site_url) %></strong>
<em>on <%= comment.created_at.strftime('%b %d, %Y at %H:%M') %></em>
<%=simple_format comment.content %><hr>
<p>
<%= link_to("Edit", edit_comment_path(comment)) if can? :update, #comment %>
<% end %>
<%= link_to("Destroy", comment, :method => :delete, :confirm => "Are you sure?") if can? :destroy, #comment %>
</p>
</div></div>
<% end %>
</div></div>
song_controller.rb
class SongsController < ApplicationController
before_filter :authenticate_user!, only: [:create ,:edit, :update, :destroy, :vote_for_song]
before_action :set_song, only: [:show, :edit, :update, :destroy, :vote_for_song]
def vote_for
#song = Song.find(params[:id])
current_user.vote_for(#song)
#song.plusminus = #song.votes_for
#song.save
respond_to do |format|
format.js { render 'update_votes' }
end
end
def vote_against
#song = Song.find(params[:id])
current_user.vote_against(#song)
respond_to do |format|
format.js { render 'update_votes' }
end
end
def new_songs
#songs = Song.order "id DESC"
end
# GET /Songs
# GET /Songs.json
def index
if params[:genre]
#songs = Song.tagged_with(params[:genre]).paginate(:page => params[:page], :per_page => 15)
else
#songs = Song.order('plusminus').paginate(:page => params[:page], :per_page => 15)
end
end
# GET /Songs/1
# GET /Songs/1.json
def show
#comment = Comment.new(song: #song)
end
# GET /Songs/new
def new
#song = Song.new
end
# GET /Songs/1/edit
def edit
end
# POST /Songs
# POST /Songs.json
def create
#song = Song.new(song_params)
respond_to do |format|
if #song.save
format.html { redirect_to #song, notice: 'Song was successfully created.' }
format.json { render action: 'show', status: :created, location: #song }
else
format.html { render action: 'new' }
format.json { render json: #song.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /Songs/1
# PATCH/PUT /Songs/1.json
def update
respond_to do |format|
if #song.update(song_params)
format.html { redirect_to #song, notice: 'Song was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #song.errors, status: :unprocessable_entity }
end
end
end
# Song /Songs/1
# Song /Songs/1.json
def destroy
#song.destroy
respond_to do |format|
format.html { redirect_to songs_url }
format.json { head :no_content }
end
end
private
def set_song
#song = Song.find(params[:id])
end
def song_params
params.require(:song).permit(:title, :artist, :url, :track, :user_id, :tag_list)
end
end

In dev and prod env you call:
ENV['my bucketname']
In model:
ENV['bucketname']
Also a good name for env variable would be:
ENV['MY_BUCKETNAME']
In your case:
ENV['AWS_BUCKET']
config.paperclip_defaults = {
:storage => :s3,
:bucket => ENV['BUCKETNAME'],
:s3_credentials => { :access_key_id => ENV['my access key'], :secret_access_key => ENV['my secret access key'] } }

Related

/YYYY/MM/Title-Slug URL structure with Friendly_Id throwing error in Edit Action

Good Day,
Excuse me for the noob question.
In my rails app I have /YYYY/MM/DD/Title-Slug URL structure with Friendly_Id .
news_controller.rb
class NewsController < ApplicationController
before_action :set_news, only: [:show, :edit, :update]
before_action :authenticate_user!, except: [:show, :index, :search ]
def index
if params[:search]
#news = News.search(params[:search]).paginate(:page => params[:page], :per_page => 12).order("created_at DESC")
else
#news = News.where( state: true ).paginate(:page => params[:page], :per_page => 12).order('id DESC')
end
end
def latest_news
if current_user.admin?
#news = News.paginate(:page => params[:page], :per_page => 12).order('id DESC')
else
flash[:error] = "you are not authorised to visit this section"
redirect_to root_path
end
end
def new
if current_user.state == true
#news = News.new
else
flash[:error] = "your account has not been activated"
redirect_to root_path
end
end
def show
#news_photos = #news.news_photos
end
def create
#news = News.new(news_params)
respond_to do |format|
if #news.save
if params[:images]
params[:images].each do |image|
#news.news_photos.create(image: image)
end
end
#news_photos = #news.news_photos
format.html { redirect_to show_news_path(#news.year,#news.month,#news.date,#news ), notice: 'News was successfully created.' }
format.json { render :show, status: :created, location: #news }
else
render :new
end
end
end
def edit
#news_photos = #news.news_photos
end
def update
respond_to do |format|
if current_user.admin?
if #news.update(admin_news_params)
if params[:images]
params[:images].each do |image|
#news.news_photos.create(image: image)
end
end
#redirect_to root_path, notice: "Updated..."
# redirect_to latest_news_path, notice: "Updated..."
format.html { redirect_to show_news_path(#news.year,#news.month,#news.date,#news ), notice: 'News was successfully edited' }
# format.json { render :show, status: :created, location: #news }
else
render :edit
end
else
if #news.update(news_params)
if params[:images]
params[:images].each do |image|
#news.news_photos.create(image: image)
end
end
# redirect_to news_index_path, notice: "Updated..."
#redirect_to latest_news_path, notice: "Updated..."
format.html { redirect_to show_news_path(#news.year,#news.month,#news.date,#news ), notice: 'News was successfully edited.' }
# format.json { render :show, status: :created, location: #news }
else
render :edit
end
end
end
end
def destroy
#news = News.find(params[:id])
#news.destroy
respond_to do |format|
format.html { redirect_to news_index_path }
# format.json { head :no_content }
end
end
private
def set_news
#news = News.find(params[:id])
end
def news_params
params.require(:news).permit( :title, :description, :category, :keywords, :user_id, :email, :user_name)
end
def admin_news_params
params.require(:news).permit( :title, :description, :category, :keywords, :user_id, :email, :user_name, :state)
end
end
news_helper.rb
module NewsHelper
def show_news_path(news)
"/news/#{news.year}/#{news.month}/#{news.date}/#{news.slug}"
end
end
news.rb
class News < ApplicationRecord
extend FriendlyId
include PgSearch
has_many :news_photos
friendly_id :slug_candidates, use: [:slugged, :finders, :history]
def slug_candidates
[ :title,
[:title, :id]
]
end
def year
created_at.localtime.strftime("%Y")
end
def month
created_at.localtime.strftime("%m")
end
def date
created_at.localtime.strftime("%d")
end
end
routes.rb
Rails.application.routes.draw do
resources :news, :except => [:latest_news, :search, :show, :edit, :update]
root :to => "news#index"
scope 'news' do
get '/:year/:month/:date/:id', to: 'news#show', as: 'show_news'
get '/:year/:month/:date/:id/edit', to: 'news#edit', as: 'edit_news'
patch '/:year/:month/:date/:id', to: 'news#update'
put '/:year/:month/:date/:id', to: 'news#update'
delete '/:year/:month/:date/:id', to: 'news#destroy'
end
end
_form.html.erb
<div class="row">
<div class="col-md-8 col-md-offset-2">
<%= form_for #news, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
<div class="row">
<div class="col-md-12">
<%= f.label :title, :class => 'control-label' %>
<div class="form-group">
<%= f.text_field :title, :class => 'form-control' %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<%= f.label :keywords, :class => 'control-label' %>
<div class="form-group">
<%= f.text_field :keywords, :class => 'form-control' %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<%= f.label :description, :class => 'control-label' %>
<div class="form-group">
<%= f.text_area :description, :class => 'form-control', id: "input" %>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<label>Upload Image</label>
<div class="form-group">
<span class="btn btn-success btn-file">
<i class="fa fa-cloud-upload fa-lg"></i> Upload Photos
<%= file_field_tag "images[]", type: :file, multiple: true %>
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= f.submit nil, :class => 'btn btn-info' %>
</div>
</div>
<% end %>
</div>
</div>
here's what works:
news/index
/news/2017/4/27/example
Creating a new post
Destroying a post
What doesn't work:
Editing a post (the edit page with the form will render, but after submitting my changes i am getting the aforementioned error - and the changes never make it to the DB)
error:
ActionController::RoutingError (No route matches [PATCH] "/news/example"):
I have fallowed the below post to implement the date based slugs:
/YYYY/MM/Title-Slug URL structure with Friendly_Id Solution Chokes on #edit
I DONT UNDERSTAND WHAT I HAVE GONE WRONG IN news_helper.rb
Any help is Highly Appreciated.Thanks in Advance
try below code:
Rails.application.routes.draw do
resources :news, :except => [:latest_news, :search, :show, :edit]
remove :update from except
It's because you've disabled the update action in your routes
resources :news, :except => [:latest_news, :search, :show, :edit, :update]
The solution is to allow the update by removing it from the except clause like this
resources :news, except: [:latest_news, :search, :show, :edit]
The user will never see this url unless they "view-source" it so it doesn't matter for usability sake.

Added new field is not saved in mongodb in rails?

grading.rb
class Grading
require 'autoinc'
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Autoinc
field :quantity, type: Float
field :count, :type => Float
field :grade_id, type: Integer
field :batch_id, type: Integer
field :variety_id, type: Integer
field :serial_id, :type => Integer
field :soaked, :type => Boolean
# Mongoid AutoInc
increments :serial_id
# Associations
belongs_to :grade
belongs_to :variety
belongs_to :batch
has_many :grading_weighments, :dependent=> :destroy
# validations
validates_presence_of :grade_id,:batch_id,:variety_id
validates_presence_of :quantity , numericality: {:greater_than => 0}
validates_presence_of :count ,numericality: {:greater_than_or_equal_to => 10, :less_than_or_equal_to => 150}
attr_accessor :weights
accepts_nested_attributes_for :grading_weighments, :allow_destroy => true
end
gradingcontroller.rb
class GradingsController < ApplicationController
before_action :set_grading, only: [:show, :edit, :update, :destroy]
# load_and_authorize_resource
# GET /gradings
# GET /gradings.json
def index
#gradings = Grading.all.order('date DESC')
#q = Batch.search(params[:q])
#batches = #q.result(:distinct => true).in(status:["HLQDone","GradingDone"]).order('updated_at ASC').page(params[:page]).per(5)
# #batches = Batch.all.order('created_at DESC').page(params[:page]).per(5) .where(status: "HLQ_Done")
#grades = Grade.all.map{|g| [g.id.to_s,g.name]}
#varieties = Variety.all.map{|v| [v.id.to_s,v.name]}
respond_to do |format|
format.js
format.html
end
end
# GET /gradings/1
# GET /gradings/1.json
def show
end
# GET /gradings/new
def new
#grading = Grading.new
end
# GET /gradings/1/edit
def edit
end
# POST /gradings
# POST /gradings.json
def create
#grades = Grade.all.map{|g| [g.id.to_s,g.name]}
#varieties = Variety.all.map{|v| [v.id.to_s,v.name]}
#grading = Grading.new(grading_params)
#batch= #grading.batch
weights=params[:grading][:weights]
#grading.quantity= weights.map! { |i| i.to_f }.sum
respond_to do |format|
if #grading.save
#grading_weighments=GradingWeighment.new
#grading_weighments.grading_id =#grading.id
#grading_weighments.weights =weights.join(',')
#grading_weighments.save
format.html { redirect_to gradings_path, notice: 'Grading was successfully created.' }
format.json { render action: 'show', status: :created, location: #grading }
format.js
else
format.html { render action: 'new' }
format.json { render json: #grading.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gradings/1
# PATCH/PUT /gradings/1.json
def update
g=[]
puts "#{params[:grading][:grading_weighments_attributes]}"
params[:grading][:grading_weighments_attributes].each do |key,value|
g<<value[:weights]
end
puts "=============#{g}"
q= g.map{ |i| i.to_f }.sum
puts "==========aes==#{q}"
#grading.update_attributes(quantity: q)
#gw= GradingWeighment.find_or_create_by(grading_id: #grading.id)
#gw.update_attributes(weights: g.join(','))
respond_to do |format|
if #grading.update(grading_params)
#grades = Grade.all.map{|g| [g.id.to_s,g.name]}
#varieties = Variety.all.map{|v| [v.id.to_s,v.name]}
format.html { redirect_to gradings_path, notice: 'Grading was successfully updated.' }
format.json { respond_with_bip(#grading) }
format.js
else
format.html { render action: 'edit' }
format.json { render json: #grading.errors, status: :unprocessable_entity }
format.js
end
end
end
# DELETE /gradings/1
# DELETE /gradings/1.json
def destroy
#grading_id=#grading.id
batch_number= #grading.batch.batch_number
#grading.destroy
respond_to do |format|
#del_batch = Batch.find_by(batch_number: batch_number)
#length=#del_batch.gradings.length
#del_batch.update_attributes(status: "HLQ_Done") if #length==0
format.html { redirect_to gradings_url }
format.json { head :no_content }
format.js
end
end
def fetch_weights
#grading_weighments=GradingWeighment.find_by(grading_id: params[:id]).weights
#grading=Grading.find(params[:id])
(#grading.grading_weighments.first.weights.split(',').length-1).times {#grading.grading_weighments.build}
respond_to do |format|
format.html { render :nothing => true, :status => 200, :content_type => 'text/html'}
format.json { head :no_content }
format.js
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_grading
#grading = Grading.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def grading_params
params.require(:grading).permit(:quantity,:batch_id,:variety_id,:grade_id,:count, :weights,:grading_weighments_attributes, :soaked)
end
end
list.html.erb
<thead>
<tr>
<th>Count</th>
<th>Grade</th>
<th>Variety</th>
<th>Quantity</th>
<th>Soaked</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<%batch= #batch if !batch%>
<%if batch.gradings.length==0%>
<tr><td colspan="5" class="warning">Grading is not done for batch with number <%=batch.batch_number%></td></tr>
<%else%>
<%gradings=batch.gradings.order('created_at DESC')%>
<%gradings.each do |grading|%>
<tr id="<%=grading.id%>">
<td><%= best_in_place grading, :count, :as => :input, required:true%></td>
<td><%= best_in_place grading, :grade_id, :as => :select, :collection => #grades %></td>
<td><%= best_in_place grading, :variety_id, :as => :select, :collection => #varieties %></td>
<td><%= best_in_place grading, :quantity, :as => :input%></td>
<td><%= best_in_place grading, :soaked, :as => :input, required:true%></td>
<td>
<%= link_to "getweights/#{grading.id}", method: :get, :remote => true ,class:'btn btn-info' do%>
<i class="fa fa-plus"></i>
<% end %>
<%= link_to grading, method: :delete, remote:true,data: { confirm: 'Are you sure?' } ,title:'Delete this grading', class:'btn btn-danger' do%>
<i class="fa fa-trash-o"></i>
<%end%>
</td>
</tr>
<%end%>
<%end%>
</tbody>
</table>
new.grading.html.erb
<div class="form-group">
<%= f.label :soaked ,class:"sr-only"%>
<%= f.select :soaked ,options_for_select(["Soaked", "Un-soaked"]), {:include_blank => "Select Soaking"}, class: "form-control" , autocomplete:"off", required: true %>
</div>
Here i am added new field called as "field :soaked, :type => Boolean", this field is not saved in database and not showing in views. How can solve this problem please help me.
Note: I passed grading params (soaked) also.
Try this:
<%= f.select :active, [['Soaked', true], ['Un-soaked', false]] %>
soaked will only accept TRUE or FALSE, while you are trying to save "Soaked", "Un-soaked"
<%= f.check_box :soaked %>
You can use CHECKBOX.
If you still want to use "Soaked" and "Un-soaked". You can apply check in your controller. If Soaked is selected then save TRUE else FALSE
Try This One
<%= f.select :soaked, options_for_select([['Soaked', true], ['Un-soaked', false]]) %>

Rails : error param is missing or the value is empty : annonce

I want to creat a classified ads website for a project in school and I try to create a form to send a message by email at a member of the website. The email adress is contained in a model which is name "Membre" and this model is link at a model who is name "Annonce" which contained the ad.
But when I try to create that, I have this error :
param is missing or the value is empty: annonce
app/controllers/annonces_controller.rb:104:in `annonce_params'
app/controllers/annonces_controller.rb:29:in `create'
Here the Ad controller :
class AnnoncesController < ApplicationController
before_action :set_annonce, only: [:show, :edit, :update, :destroy]
before_filter :authenticate_user!, :except => [:index]
# GET /annonces
# GET /annonces.json
def index
#annonces = Annonce.all
end
# GET /annonces/1
# GET /annonces/1.json
def show
end
# GET /annonces/new
def new
#annonce = Annonce.new
end
# GET /annonces/1/edit
def edit
end
# POST /annonces
# POST /annonces.json
def create
#annonce = Annonce.new(annonce_params)
#annonce.membre_id = current_membre.id
respond_to do |format|
if #annonce.save
format.html { redirect_to #annonce, notice: t('annonce_cree_succes') }
format.json { render :show, status: :created, location: #annonce }
else
format.html { render :new }
format.json { render json: #annonce.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /annonces/1
# PATCH/PUT /annonces/1.json
def update
respond_to do |format|
if #annonce.update(annonce_params)
format.html { redirect_to #annonce, notice: t('annonce_cree_succes') }
format.json { render :show, status: :ok, location: #annonce }
else
format.html { render :edit }
format.json { render json: #annonce.errors, status: :unprocessable_entity }
end
end
end
# DELETE /annonces/1
# DELETE /annonces/1.json
def destroy
#annonce.destroy
respond_to do |format|
format.html { redirect_to annonces_url, notice: t('annonce_destroy_succes') }
format.json { head :no_content }
end
end
# GET /annonces/contact/1
def contact
#form_contact = FormContact.new
if #form_contact.valid?
#MembreMailer.email_contact(Membre.where(:id => #annonce.membre_id ),current_membre,#annonce,#message)
#annonce = Annonce.find(params[:id])
#recepteur = Membre.where(:id => #annonce.membre_id )
#membre = current_membre
mail(:to => "#{recepteur.pseudo} <#{recepteur.email}>", subject: 'Reponse à l\'une de vos annnonces')
redirect_to root
end
end
# GET /annonces/report/1
def report
#annonce = Annonce.find(params[:id])
end
private
def authenticate_user!
if membre_signed_in?
#super
else
redirect_to login_path, :notice => 'Merci de vous connecter pour effecter cette action'
## if you want render 404 page
## render :file => File.join(Rails.root, 'public/404'), :formats => [:html], :status => 404, :layout => false
end
end
# Use callbacks to share common setup or constraints between actions.
def set_annonce
#annonce = Annonce.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def annonce_params
params.require(:annonce).permit(:id, :titre, :corps, :prix, :membre_id, :categorie, :created_at, :image)
end
Here the view contact :
<div class="col-md-offset-2 col-md-8 well panel panel-default">
<h2 class='panel-heading text-center'><%= t('contacter') %></h2>
<div class="panel-body text-center">
<%= form_for(:form_contact, :url => {:action => :create}) do |f| %>
<div class="field block-center">
<%= f.label "message" %></br>
<%= f.text_area(:message, size: "50x15")%>
</div></br>
<div class="actions form-group col-md-offset-3 col-md-6">
<%= submit_tag t('envoyer'), :class => "btn btn-large btn-block btn-primary" %>
</div>
<% end %>
</div>
</div>
<p class='row'> </p>
And here the FormContact class:
class FormContact < ActiveForm::Base
attr_accessor :message
validates_presence_of :message
def new
#form_contact = FormContact.new(login_form)
end
def index
#form_contact = FormContact.new
end
private
def login_form
params.require(:form_contact).permit(:message)
end
end
How can I fix that ?
Thanks in advance
This is routing error, you should call the create method of FormContactsController, not AnnoncesController create method.
<%= form_for(:form_contact, :url => {:controller => "FormContactsController", :action => :create}) do |f| %>

unable to upload an image using the paperclip gem

having installed the latest version of paperclip , i get an error every time i try and upload an image , i can click on the upload button , select my image but when i try to create a listing/image i get error Paperclip::Errors::MissingRequiredValidatorError in ListingsController#create Paperclip::Errors::MissingRequiredValidatorError ..imagemagick installed as well
listings.controller.rb
class ListingsController < ApplicationController
before_action :set_listing, only: [:show, :edit, :update, :destroy]
# GET /listings
# GET /listings.json
def index
#listings = Listing.all
end
# GET /listings/1
# GET /listings/1.json
def show
end
# GET /listings/new
def new
#listing = Listing.new
end
# GET /listings/1/edit
def edit
end
# POST /listings
# POST /listings.json
def create
#listing = Listing.new(listing_params) **<------ERROR**
respond_to do |format|
if #listing.save
format.html { redirect_to #listing, notice: 'Listing was successfully created.' }
format.json { render action: 'show', status: :created, location: #listing }
else
format.html { render action: 'new' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /listings/1
# PATCH/PUT /listings/1.json
def update
respond_to do |format|
if #listing.update(listing_params)
format.html { redirect_to #listing, notice: 'Listing was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #listing.errors, status: :unprocessable_entity }
end
end
end
# DELETE /listings/1
# DELETE /listings/1.json
def destroy
#listing.destroy
respond_to do |format|
format.html { redirect_to listings_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_listing
#listing = Listing.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def listing_params
params.require(:listing).permit(:name, :description, :price, :image)
end
end
listing.rb
class Listing < ActiveRecord::Base
has_attached_file :image, :styles => { :medium => "200x", :thumb => "100x100>" }, :default_url => "missing.jpg"
end
_form.html.erb
<%= form_for(#listing, :html => { :multipart => true }) do |f| %>
<% if #listing.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#listing.errors.count, "error") %> prohibited this listing from being saved:</h2>
<ul>
<% #listing.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :price %>
<%= f.text_field :price, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :image %>
<%= f.file_field :image, class: "form-control" %>
</div>
<div class="form-group">
<%= f.submit class: "btn btn-primary" %>
</div>
<% end %>
You have to add a validation of content type in your model:
validates_attachment_content_type :image, content_type: %w(image/jpeg image/jpg image/png)

rails: "unknown action" message when action is clearly specified

I had hard time to figure out why I've been getting "unknown action" error message when I was do some editing:
Unknown action
No action responded to 11. Actions: bin, create, destroy, edit, index, new, observe_new, show, tag, update, and vote
you can see that Rails did mention each action in the above list - update. And in my form, I did specify action = "update".
I wonder if some friends could kindly help me with the missing links...
here is the code:
edit.rhtml
<h1>Editing tip</h1>
<% form_tag :action => 'update', :id => #tip do %>
<%= render :partial => 'form' %>
<p>
<%= submit_tag_or_cancel 'Save Changes' %>
</p>
<% end %>
_form.rhtml
<%= error_messages_for :tip %>
<p><label>Title<br/>
<%= text_field :tip, :title %></label></p>
<p><label>Categories<br/>
<%= select_tag('categories[]', options_for_select(Category.find(:all).collect {|c| [c.name, c.id] }, #tip.category_ids), :multiple => true ) %></label></p>
<p><label>Abstract:<br/>
<%= text_field_with_auto_complete :tip, :abstract %></label></p>
<p><label>Name: <br/>
<%= text_field :tip, :name %></label></p>
<p><label>Link: <br/>
<%= text_field :tip, :link %></label></p>
<p><label>Content<br/>
<%= text_area :tip, :content, :rows => 5 %></label></p>
<p><label>Tags <span>(space separated)</span><br/>
<%= text_field_tag 'tags', #tip.tag_list, :size => 40 %></label></p>
class TipsController < ApplicationController
before_filter :authenticate, :except => %w(index show)
# GET /tips
# GET /tips.xml
def index
#tips = Tip.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #tips }
end
end
# GET /tips/1
# GET /tips/1.xml
def show
#tip = Tip.find_by_permalink(params[:permalink])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #tip }
end
end
# GET /tips/new
# GET /tips/new.xml
def new
#tip = session[:tip_draft] || current_user.tips.build
end
def create
#tip = current_user.tips.build(params[:tip])
#tipMail=params[:email]
#if tipMail
# TipMailer.deliver_email_friend(params[:email], params[:name], tip)
# flash[:notice] = 'Your friend has been notified about this tip'
#end
#tip = current_user.tips.build(params[:tip])
#tip.categories << Category.find(params[:categories]) unless params[:categories].blank?
#tip.tag_with(params[:tags]) if params[:tags]
if #tip.save
flash[:notice] = 'Tip was successfully created.'
session[:tip_draft] = nil
redirect_to :action => 'index'
else
render :action => 'new'
end
end
def edit
#tip = Tip.find(params[:id])
end
def update
#tip = Tip.find(params[:id])
respond_to do |format|
if #tip.update_attributes(params[:tip])
flash[:notice] = 'Tip was successfully updated.'
format.html { redirect_to(#tip) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #tip.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#tip = Tip.find(params[:id])
#tip.destroy
respond_to do |format|
format.html { redirect_to(tips_url) }
format.xml { head :ok }
end
end
def observe_new
session[:tip_draft] = current_user.tips.build(params[:tip])
render :nothing => true
end
end
the quick answer is that form_tag doesn't support :action as an option, you want to be passing a string as a path in. A slightly longer answer is you shouldn't be using form_tag anyways for a model edit form, you should be using form_for.
what rails are you using? .rhtml is pretty old, rails generators should be giving you .html.erb files. if it is something even remotely recent, you should be able to use
<% form_for #tip do |f| %>
<%= f.label :title, 'Title' %><br />
<%= f.text_field %>
... etc
<% end %>

Resources