Rails 3.2.11 Paperclip - ruby-on-rails

Rails 3.2.11 Paperclip polymorphic nested attachment, the uploaded images is never saved! Maybe I should add an assets id to every table which requires images?
What would stop paperclip from uploading and saving files?
Thank you in advanced
error message:
Connecting to database specified by database.yml
Started GET "/videos/" for 31.54.205.49 at Wed May 15 06:51:33 -0500 2013
Processing by VideosController#index as HTML
Rendered videos/index.html.erb within layouts/application (111.6ms)
Completed 500 Internal Server Error in 227ms
ActionView::Template::Error (undefined method `attachment_file_name' for #<Video::Cover:0x6929d69365c0>):
3: <div class="video">
4:
5: <%- video.covers.each do |cover| %>
6: <div class="video_cover"><%=link_to image_tag (cover.url(:small)), video %></div>
7: <% end %>
8:
9:
app/models/assets.rb:4:in `__send__'
app/models/assets.rb:4:in `url'
app/views/videos/index.html.erb:6:in `_app_views_videos_index_html_erb__730847823_57814209936840'
app/views/videos/index.html.erb:5:in `_app_views_videos_index_html_erb__730847823_57814209936840'
app/views/videos/index.html.erb:1:in `each'
app/views/videos/index.html.erb:1:in `_app_views_videos_index_html_erb__730847823_57814209936840'
app/controllers/videos_controller.rb:10:in `index'
Schema:
ActiveRecord::Schema.define(:version => 20130514180732) do
create_table "assets", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "type"
t.integer "assetable_id"
t.string "assetable_type"
t.string "attachement_type"
t.string "attachement_file_name"
t.string "attachement_content_type"
t.integer "attachement_file_size"
t.datetime "attachement_updated_at"
end
create_table "photos", :force => true do |t|
t.string "title"
t.text "body"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "videos", :force => true do |t|
t.string "title"
t.text "body"
t.string "url"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
models:
class Assets < ActiveRecord::Base
belongs_to :assetable, :polymorphic => true delegate :url, :to => :attachment
end
class Video < ActiveRecord::Base
attr_accessible :body, :title, :url, :assets_attributes, :cover
#has_many :images, :as => :assetable, :class_name => "Video::Image", :dependent => :destroy
has_many :covers, :as => :assetable, :class_name => "Video::Cover", :dependent => :destroy
accepts_nested_attributes_for :covers, :allow_destroy => true
class Video::Cover < Assets
has_attached_file :attachment, :styles => { :small => "300x0>", :large => "800x0>" }
end
end
The video controller:
class VideosController < ApplicationController
#load_and_authorize_resource
# GET /videos
# GET /videos.xml
def index
#videos = Video.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #videos }
end
end
# GET /videos/1
# GET /videos/1.xml
def show
#video = Video.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #video }
end
end
# GET videos/new
# GET /videos/new.xml
def new
#video = Video.new
1.times do #video.covers.build end
#40.times do #video.images.build end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #video }
end
end
# GET /collections/1/edit
def edit
#video = Video.find(params[:id])
1.times do#video.covers.build end
#1.times do #video.images.build end
end
# POST /videos
# POST /videos.xml
def create
#video = Video.new(params[:video])
respond_to do |format|
if #video.save
format.html { redirect_to(#video, :notice => 'Video was successfully created.') }
format.xml { render :xml => #video, :status => :created, :location => #video }
else
format.html { render :action => "new" }
format.xml { render :xml => #video.errors, :status => :unprocessable_entity }
end
end
end
# PUT /videos/1
# PUT /videos/1.xml
def update
#video = Video.find(params[:id])
respond_to do |format|
if #video.update_attributes(params[:video])
format.html { redirect_to(#video, :notice => 'Video was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #video.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /videos/1
# DELETE /videos/1.xml
def destroy
#video = Video.find(params[:id])
#video.destroy
respond_to do |format|
format.html { redirect_to(videos_url) }
format.xml { head :ok }
end
end
end
Video form:
<div id="form_bk">
<div id="field_left">
<%= form_for #video, :html => {:multipart => true} do |f| %>
<% if #video.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#video.errors.count, "error") %> prohibited this collection from being saved:</h2>
<ul>
<% #video.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div id="cover">
<br />
<h2>Cover Image</h2>
<%= f.fields_for :covers do |cover| %>
<% if cover.object.new_record? %>
<p><%= cover.file_field :attachment %></p>
<% end %>
<% end %>
<%= f.fields_for :covers do |cover| %>
<% unless cover.object.new_record? %>
<br />
<p>
<%=image_tag cover.object.url(:small) %><br />
<br /> Delete cover <%= cover.check_box :_destroy %><br /><br />
</p>
<% end %>
<% end %>
</div>
<div id="form_right">
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div></div>
<div class="field">
<%= f.label :url %><br />
<%= f.text_area :url %>
</div></div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<br />
</div>
index view:
<% #videos.each do |video| %>
<div class="video">
<%= video.covers.each do |cover| %>
<div class="video_cover"><%=link_to image_tag (cover.url(:small)), video %></div>
<% end %>
<div class="video_title">
<%=link_to video.title, video %>
<%= video.body %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
<%= link_to 'Destroy', video, :confirm => 'Are you sure?', :method => :delete %>
</div>
</div>
<% end %>
<br /><br /><br />
<%= link_to 'New Video', new_video_path %>

Related

AJAX is not working in rails 6 with my code , my create.js.erb code is not working , i have to reload every time to show my message in index view

messages_controller.rb FILE:
class MessagesController < ApplicationController
def index
#messages = Message.all
#message = Message.new
end
def create
#message = Message.new(message_params)
#messages = Message.all
respond_to do |format|
if #message.save
format.html { redirect_to #message, notice: 'message was successfully created'}
format.js
format.json { render :show, status: :created, location: #message }
end
end
end
private
def message_params
params.require(:message).permit(:body)
end
end
index.html.erb FILE:
<table>
<tbody>
<%= render partial: 'message', collection: #messages %>
</tbody>
</table>
<%= render 'form', message: #message %>
# i remove the code from CREATE.JS.ERB but it results in no change in server (port:3000)#
create.js.erb FILE:
$('table#bands tbody').append("<%= j render #message %>");
_message.html.erb FILE:
<tr>
<td><%= message.body %></td>
</tr>
_form.html.erb FILE:
<%= form_with(model: message) do |f| %>
<div class="col-sm-8">
<%= f.text_area :body, class: "form-control", placeholder: "Message Body" %>
</div>
<div class="btn-group">
<%= f.submit class: 'btn btn-primary' %>
</div>
<% end %>
routes.rb FILE:
Rails.application.routes.draw do
resources :messages
root 'messages#index'
end
schema.rb FILE:
ActiveRecord::Schema.define(version: 2020_07_23_045320) do
create_table "messages", force: :cascade do |t|
t.string "body"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
Ruby on rails

Paperclip upload causes update.js.erb to output code as text

I've been having this problem with Paperclip for a while. New/Edit form submits and saves/updates, but create.js and update.js renders the code (that normally would be a view) as text to http://localhost:3000/albums/9.js (if it's the 9th album being updated), instead of a view in a modal on localhost:3000.
so instead of rendering a view, i get this text on /albums/9.js: $("#actionEdit").html("Album Updated.")
album model
belongs_to :band
has_many :songs
has_attached_file :album_artwork_1,
styles: { thumb: ["64x64#", :jpg] },
convert_options: { thumb: "-strip",
original: "-strip" }
has_attached_file :album_artwork_2,
styles: { thumb: ["64x64#", :jpg] },
convert_options: { thumb: "-strip",
original: "-strip" }
has_attached_file :album_artwork_3,
styles: { thumb: ["64x64#", :jpg] },
convert_options: { thumb: "-strip",
original: "-strip" }
do_not_validate_attachment_file_type :album_artwork_1
do_not_validate_attachment_file_type :album_artwork_2
do_not_validate_attachment_file_type :album_artwork_3
validates :album_name, presence: true
validates :album_release_date, presence: true
albums controller
def new
binding.pry
#band = Band.find(params[:band])
authorize #band, :admin?
#album = Album.new
respond_to do |format|
format.js
end
end
def create
#band = Band.find(params[:album][:band].to_i)
authorize #band, :admin?
#album = #band.albums.build(album_params)
if #album.save
#records = []
#band.albums.each do |album|
#records << album
end
#band.eps.each do |ep|
#records << ep
end
#band.songs.each do |song|
#records << song
end
#records_ordered = #records #.sort.reverse!
respond_to do |format|
format.js
end
else
respond_to do |format|
format.js
end
end
end
def edit
#band = Band.find(params[:band])
authorize #band, :admin?
#album = Album.find(params[:id])
respond_to do |format|
format.js
end
end
def update
binding.pry
#band = Band.find(params[:album][:band])
authorize #band, :admin?
#album = Album.find(params[:id])
if #album.update(album_params)
respond_to do |format|
format.js
end
else
#fail = "w4rd"
respond_to do |format|
format.js
end
end
end
form
<%=simple_form_for(#album, remote: true, :authenticity_token => true, format: :js) do |f| %>
<% if #album.album_artwork_1.present? %>
<%= link_to image_tag(#album.album_artwork_1.url(:thumb), class: 'media-object'), #album.album_artwork_1.url, target: '_blank' %>
<% end %>
<div class="form-group">
<%= f.input :album_artwork_1, as: :file %>
</div>
<% if #album.album_artwork_2.present? %>
<%= link_to image_tag(#album.album_artwork_2.url(:thumb), class: 'media-object'), #album.album_artwork_2.url, target: '_blank' %>
<% end %>
<div class="form-group">
<%= f.input :album_artwork_2, as: :file %>
</div>
<% if #album.album_artwork_3.present? %>
<%= link_to image_tag(#album.album_artwork_3.url(:thumb), class: 'media-object'), #album.album_artwork_3.url, target: '_blank' %>
<% end %>
<div class="form-group">
<%= f.input :album_artwork_3, as: :file %>
</div>
<br><br>
<div id="albumsubmit">
<% if params[:action] === "edit" %>
<div class="form-actions">
<%= f.button :submit, "Update Album", class: "btn btn-primary" %>
</div>
<% else %>
<div class="form-actions">
<%= f.button :submit, "Create Album", class: "btn btn-primary" %>
</div>
<% end %>
</div>
<% end %>
update.js.erb
$("#actionEdit").html("<%= j render 'updated' %>")
schema
create_table "albums", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "album_artwork_1_file_name"
t.string "album_artwork_1_content_type"
t.integer "album_artwork_1_file_size"
t.datetime "album_artwork_1_updated_at"
t.string "album_artwork_2_file_name"
t.string "album_artwork_2_content_type"
t.integer "album_artwork_2_file_size"
t.datetime "album_artwork_2_updated_at"
t.string "album_artwork_3_file_name"
t.string "album_artwork_3_content_type"
t.integer "album_artwork_3_file_size"
t.datetime "album_artwork_3_updated_at"
params coming into #update
[1] pry(#<AlbumsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"B/g/tnhObi6YmY6gqY0hTzJyiewshxVN6S1Dv+1yspGiRQZAlr8qdRiMtDyOh1/1VYvmr1FW9AsClLnW6xt9rg==", "album"=>{"band"=>"1", "album_name"=>"Test", "album_release_date"=>"2017-04-29", "produced_by"=>"", "recorded_at"=>"", "engineered_by"=>"", "second_engineers"=>"", "mixed_by"=>"", "mastered_by"=>"", "artwork_by"=>"", "photography_by"=>"", "art_direction_by"=>"", "construction_by"=>"", "booking"=>"", "litigation"=>"", "additional_musicians"=>"", "copyright"=>"", "websites"=>"", "contacts"=>"", "other"=>"", "album_artwork_2"=>#<ActionDispatch::Http::UploadedFile:0x007f681a3b4ca8 #tempfile=#<Tempfile:/tmp/RackMultipart20170416-32079-mie4xo.jpg>, #original_filename="c.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"album[album_artwork_2]\"; filename=\"c.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Update Album", "controller"=>"albums", "action"=>"update", "id"=>"7", "format"=>"js"} permitted: false>
[2] pry(#<AlbumsController>)>
Apparently you can't upload via remote: true without the gem remotipart, which resolved the issue.

Building nested form questions based on a 3rd model

I want to build a form for entries, where a couple of contest_questions are predicted by the user.
That means I dynamically wants to fetch the contest_questions related to the tipster-contest and then letting the user register an entry with predictions for each of those questions.
How can I do this? As of now I the fields are not showing up since <%= f.fields_for :predictions do |prediction| %>does not execute within the contest_question block and if I change it to contest_question.fields_for ...I get a
undefined method `fields_for' for #
tipster_contest.rb
class TipsterContest < ActiveRecord::Base
belongs_to :bookmaker
belongs_to :game
has_many :entries
has_many :contest_questions
extend FriendlyId
friendly_id :name, use: [:slugged, :history]
enum status: { "Scheduled" => 0, "Open" => 1, "Closed" => 2, "Graded" => 3 }
scope :published?, -> { where(published: :true) }
end
entry.rb
class Entry < ActiveRecord::Base
belongs_to :user
belongs_to :tipster_contest
has_many :predictions
accepts_nested_attributes_for :predictions
end
contest_question.rb
class ContestQuestion < ActiveRecord::Base
belongs_to :tipster_contest
has_many :predictions
end
prediction.rb
class Prediction < ActiveRecord::Base
belongs_to :entry
has_one :contest_question
end
_form.html.erb
<%= form_for(#entry) do |f| %>
<% #contest.contest_questions.order(name: :asc).each do |contest_question| %>
<%= f.fields_for :predictions do |prediction| %>
<div class="field">
<%= prediction.label contest_question.name %>
<%= prediction.select(:prediction, #contest.teams) %>
</div>
<div class="field">
<%= prediction.label :wager_amount %>
<%= prediction.input :wager_amount %>
</div>
<% end %>
<% end %>
<div class="actions">
<%= f.submit "Save entry", :class => "btn btn-success" %> <%= link_to 'Back', bets_path, :class => "btn btn-danger" %>
</div>
<% end %>
And the relevant part of my schema.rb if that would be needed:
create_table "contest_questions", force: true do |t|
t.integer "tipster_contest_id"
t.string "name"
t.string "result"
t.integer "min_wager"
t.integer "max_wager"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "entries", force: true do |t|
t.integer "user_id"
t.integer "tipster_contest_id"
t.integer "bankroll"
t.integer "won"
t.string "currency"
t.boolean "entry_valid"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "predictions", force: true do |t|
t.integer "entry_id"
t.integer "contest_question_id"
t.string "prediction"
t.integer "wager_amount"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "tipster_contests", force: true do |t|
t.integer "bookmaker_id"
t.integer "game_id"
t.string "name"
t.string "tournament"
t.integer "status", default: 0
t.text "rules"
t.integer "prizepool"
t.string "currency"
t.text "payout_structure"
t.integer "tipster_wallet"
t.string "teams", default: [], array: true
t.datetime "registration_open"
t.datetime "registration_close"
t.boolean "published", default: false
t.datetime "created_at"
t.datetime "updated_at"
t.string "logo"
t.text "description"
t.string "slug"
end
add_index "tipster_contests", ["slug"], name: "index_tipster_contests_on_slug", using: :btree
Managed to figure it out and at least get it working. I don't know if the solution is any good in terms of the rails standard. Anyway here it is:
_form.html.erb
<% title("#{#contest.name}") %>
<% description("Join #{#contest.name} and use your eSports knowledge to win extra cash or in-game skins for games like CS:GO, Dota 2, etc.") %>
<p id="notice"><%= notice %></p>
<%= form_for(#entry) do |f| %>
<% if #entry.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#entry.errors.count, "error") %> prohibited this entry from being saved:</h2>
<ul>
<% #entry.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field 'tipster_contest_id', :value => #contest.id %>
<div class="t_container">
<div class="t_row">
<div class="t_left"><b>Placement</b></div>
<div class="t_middle"><b>Team</b></div>
<div class="t_right"><b>Wager Amount</b></div>
</div>
<%= f.fields_for :predictions, #predictions do |p| %>
<div class="t_row">
<div class="t_left"><%= #entry.contest_questions.order(:name => :asc)[p.index].name %></div>
<div class="t_middle"><%= p.select :prediction, #contest.teams %></div>
<div class="t_right"><%= p.text_field :wager_amount, label: "Wager amount" %></div>
<%= p.hidden_field 'contest_question_id', :value => #entry.contest_questions.order(:name => :asc)[p.index].id %>
</div>
<% end %>
</div>
</br>
<div class="actions">
<%= f.submit "Save entry", :class => "btn btn-success" %> <%= link_to 'Back', bets_path, :class => "btn btn-danger" %>
</div>
<% end %>
entries_controller.rb
class EntriesController < ApplicationController
before_action :set_entry, only: [:show, :edit, :update, :destroy]
# GET /entries
# GET /entries.json
def index
#entries_open = current_user.entries.includes(:tipster_contest).where(:tipster_contests => {status: 1})
#entries_closed = current_user.entries.includes(:tipster_contest).where(:tipster_contests => {status: 2})
#entries_graded = current_user.entries.includes(:tipster_contest).where(:tipster_contests => {status: 3})
#contests = TipsterContest.where(status: 0..1).includes(:game)
end
# GET /entries/1
# GET /entries/1.json
def show
end
# GET /entries/new
def new
if user_signed_in?
begin
#contest = TipsterContest.friendly.find(params[:contest])
redirect_to tipster_contests_path(#contest), notice: "#{#contest.name} does not accept entries at this point. Registration opens at: #{#contest.registration_open} and closes at: #{#contest.registration_close}." and return true unless #contest.status == "Open"
#entry = Entry.new(tipster_contest: #contest)
#predictions = []
#contest.contest_questions.order(name: :asc).each do |cq|
#predictions << Prediction.new(entry: #entry.id, contest_question_id: cq.id)
end
rescue
redirect_to tipster_contests_path, notice: 'Could not find a tipster-contest with that ID'
end
else
redirect_to new_user_registration_path, notice: 'You need to sign up to enter the tipster contest!'
end
end
# GET /entries/1/edit
def edit
if user_signed_in?
#contest = #entry.tipster_contest
#predictions = #entry.predictions
redirect_to tipster_contests_path, notice: 'This is not your entry to edit' and return true unless #entry.user == current_user
else
redirect_to new_user_registration_path, notice: 'You need to sign up to enter or edit a tipster contest entry!'
end
end
# POST /entries
# POST /entries.json
def create
#entry = Entry.new(entry_params)
#predictions = #entry.predictions
#contest = #entry.tipster_contest
#entry.user = current_user
#entry.won = 0
#entry.bankroll = #contest.tipster_wallet
#entry.currency = #contest.currency
respond_to do |format|
if #entry.save
format.html { redirect_to #entry, notice: 'Entry was successfully created.' }
format.json { render :show, status: :created, location: #entry }
else
format.html { render :new }
format.json { render json: #entry.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /entries/1
# PATCH/PUT /entries/1.json
def update
#contest = #entry.tipster_contest
##predictions = #entry.predictions
respond_to do |format|
if #entry.update(entry_params)
format.html { redirect_to #entry, notice: 'Entry was successfully updated.' }
format.json { render :show, status: :ok, location: #entry }
else
format.html { render :edit }
format.json { render json: #entry.errors, status: :unprocessable_entity }
end
end
end
# DELETE /entries/1
# DELETE /entries/1.json
def destroy
#entry.destroy
respond_to do |format|
format.html { redirect_to entries_url, notice: 'Entry was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_entry
#entry = Entry.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def entry_params
params[:entry].permit(:id, :tipster_contest_id, predictions_attributes: [:prediction, :wager_amount, :contest_question_id, :id])
end
end

How to pre-populate collection_check_boxes in an edit form?

GitHub repo: https://github.com/Yorkshireman/mywordlist
I've googled the hell out of this one. I'm sure there's a way, possibly requiring some code inside a html options hash, but I can't work it out. Any ideas?
When visiting the _edit_word_form.html.erb partial for a Word that DOES have one or more categories, the Categories checkboxes are all unchecked, requiring the user to select them again, even if they don't want to change the Categories.
The text fields for the :title and :description ARE pre-populated (thankfully).
_edit_word_form.html.erb:
<%= form_for(#word) do %>
<%= fields_for :word, #word do |word_form| %>
<div class="field form-group">
<%= word_form.label(:title, "Word:") %><br>
<%= word_form.text_field(:title, id: "new_word", required: true, autofocus: true, class: "form-control") %>
</div>
<div class="field form-group">
<%= word_form.label(:description, "Definition:") %><br>
<%= word_form.text_area(:description, class: "form-control") %>
</div>
<% end %>
<%= fields_for :category, #category do |category_form| %>
<% if current_user.word_list.categories.count > 0 %>
<div class="field form-group">
<%= category_form.label(:title, "Choose from existing Categories:") %><br>
<%= category_form.collection_check_boxes(:category_ids, current_user.word_list.categories.all, :id, :title) do |b| %>
<%= b.label(class: "checkbox-inline") { b.check_box + b.text } %>
<% end %>
</div>
<% end %>
<h4>AND/OR...</h4>
<div class="field form-group">
<%= category_form.label(:title, "Create and Use a New Category:") %><br>
<%= category_form.text_field(:title, class: "form-control") %>
</div>
<% end %>
<div class="actions">
<%= submit_tag("Update!", class: "btn btn-block btn-primary btn-lg") %>
</div>
<% end %>
Relevant part of the words/index.html.erb:
<% current_user.word_list.words.alphabetical_order_asc.each do |word| %>
<tr>
<td>
<%= link_to edit_word_path(word) do %>
<%= word.title %>
<span class="glyphicon glyphicon-pencil"></span>
<% end %>
</td>
<td><%= word.description %></td>
<td>
<% word.categories.alphabetical_order_asc.each do |category| %>
<a class="btn btn-info btn-sm", role="button">
<%= category.title %>
</a>
<% end %>
</td>
<td>
<%= link_to word, method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</td>
</tr>
<% end %>
words_controller.rb:
class WordsController < ApplicationController
before_action :set_word, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /words
# GET /words.json
def index
#words = Word.all
#quotes = Quote.all
end
# GET /words/1
# GET /words/1.json
def show
end
# GET /words/new
def new
#word = current_user.word_list.words.build
end
# GET /words/1/edit
def edit
end
# POST /words
# POST /words.json
def create
#word = Word.new(word_params)
respond_to do |format|
if #word.save
format.html { redirect_to #word, notice: 'Word was successfully created.' }
format.json { render :show, status: :created, location: #word }
else
format.html { render :new }
format.json { render json: #word.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /words/1
# PATCH/PUT /words/1.json
def update
#need to first remove categories from the word
#word.categories.each do |category|
#word.categories.delete category
end
#then push categories in from the category_params
if params["category"].include?(:category_ids)
(params["category"])["category_ids"].each do |i|
next if i.to_i == 0
#word.categories << Category.find(i.to_i) unless #word.categories.include?(Category.find(i.to_i))
end
end
if category_params.include?(:title) && ((params["category"])["title"]) != ""
#word.categories << current_user.word_list.categories.build(title: (params["category"])["title"])
end
respond_to do |format|
if #word.update(word_params)
format.html { redirect_to words_path, notice: 'Word was successfully updated.' }
format.json { render :show, status: :ok, location: #word }
else
format.html { render :edit }
format.json { render json: #word.errors, status: :unprocessable_entity }
end
end
end
# DELETE /words/1
# DELETE /words/1.json
def destroy
#word.destroy
respond_to do |format|
format.html { redirect_to words_url, notice: 'Word was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_word
#word = Word.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def word_params
params.require(:word).permit(:title, :description, :category_ids)
end
def category_params
params.require(:category).permit(:title, :category_ids, :category_id)
end
end
categories_controller.rb:
class CategoriesController < ApplicationController
before_action :set_category, only: [:show, :edit, :update, :destroy]
# GET /categories
# GET /categories.json
def index
#categories = Category.all
end
# GET /categories/1
# GET /categories/1.json
def show
end
# GET /categories/new
def new
#category = current_user.word_list.categories.build
end
# GET /categories/1/edit
def edit
end
# POST /categories
# POST /categories.json
def create
#category = Category.new(category_params)
respond_to do |format|
if #category.save
format.html { redirect_to #category, notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: #category }
else
format.html { render :new }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /categories/1
# PATCH/PUT /categories/1.json
def update
respond_to do |format|
if #category.update(category_params)
format.html { redirect_to #category, notice: 'Category was successfully updated.' }
format.json { render :show, status: :ok, location: #category }
else
format.html { render :edit }
format.json { render json: #category.errors, status: :unprocessable_entity }
end
end
end
# DELETE /categories/1
# DELETE /categories/1.json
def destroy
#category.destroy
respond_to do |format|
format.html { redirect_to categories_url, notice: 'Category was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_category
#category = Category.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def category_params
params.require(:category).permit(:title, :word_list_id, :category_ids)
end
end
word_lists_controller.rb:
class WordListsController < ApplicationController
before_action :set_word_list, only: [:show, :edit, :update, :destroy]
def from_category
#selected = current_user.word_list.words.joins(:categories).where( categories: {id: (params[:category_id])} )
respond_to do |format|
format.js
end
end
def all_words
respond_to do |format|
format.js
end
end
# GET /word_lists
# GET /word_lists.json
def index
#word_lists = WordList.all
end
# GET /word_lists/1
# GET /word_lists/1.json
def show
#words = Word.all
#word_list = WordList.find(params[:id])
end
# GET /word_lists/new
def new
#word_list = WordList.new
end
# GET /word_lists/1/edit
def edit
end
# POST /word_lists
# POST /word_lists.json
def create
#word_list = WordList.new(word_list_params)
respond_to do |format|
if #word_list.save
format.html { redirect_to #word_list, notice: 'Word list was successfully created.' }
format.json { render :show, status: :created, location: #word_list }
else
format.html { render :new }
format.json { render json: #word_list.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /word_lists/1
# PATCH/PUT /word_lists/1.json
def update
respond_to do |format|
if #word_list.update(word_list_params)
format.html { redirect_to #word_list, notice: 'Word list was successfully updated.' }
format.json { render :show, status: :ok, location: #word_list }
else
format.html { render :edit }
format.json { render json: #word_list.errors, status: :unprocessable_entity }
end
end
end
# DELETE /word_lists/1
# DELETE /word_lists/1.json
def destroy
#word_list.destroy
respond_to do |format|
format.html { redirect_to word_lists_url, notice: 'Word list was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_word_list
#word_list = WordList.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def word_list_params
params[:word_list]
end
end
word_list.rb:
class WordList < ActiveRecord::Base
belongs_to :user
has_many :words
has_many :categories
end
word.rb:
class Word < ActiveRecord::Base
belongs_to :word_list
has_and_belongs_to_many :categories
validates :title, presence: true
scope :alphabetical_order_asc, -> { order("title ASC") }
end
category.rb:
class Category < ActiveRecord::Base
has_and_belongs_to_many :words
belongs_to :word_list
validates :title, presence: true
scope :alphabetical_order_asc, -> { order("title ASC") }
end
schema.rb:
ActiveRecord::Schema.define(version: 20150609234013) do
create_table "categories", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "word_list_id"
end
add_index "categories", ["word_list_id"], name: "index_categories_on_word_list_id"
create_table "categories_words", id: false, force: :cascade do |t|
t.integer "category_id"
t.integer "word_id"
end
add_index "categories_words", ["category_id"], name: "index_categories_words_on_category_id"
add_index "categories_words", ["word_id"], name: "index_categories_words_on_word_id"
create_table "quotes", force: :cascade do |t|
t.text "content"
t.string "author"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
create_table "word_lists", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
create_table "words", force: :cascade do |t|
t.string "title"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "word_list_id"
end
add_index "words", ["word_list_id"], name: "index_words_on_word_list_id"
end
routes.rb:
Rails.application.routes.draw do
resources :quotes
resources :categories
resources :words
devise_for :users, controllers: { registrations: "users/registrations" }
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
root 'pages#home'
post 'create_word_and_category' => 'new_word#create_word_and_category'
end
The discussion might not be active anymore but I'll share my answer for the future visitors.
Adding "{ checked: #array.map(&:to_param) }" option as the last argument of collection_check_boxes may resolve your problem. Refer this link.
Example:
Suppose you have Software model and Platform(OS) model and want to choose one or more OS that support your software.
#views/softwares/edit.html.erb
<%= form_for #software do |f| %>
...
<%= f.label :supported_platform %>
<%= f.collection_check_boxes(:platform_ids, #platforms, :id, :platform_name, { checked: #software.platform_ids.map(&:to_param) }) %>
...
<%= f.submit "Save", class: 'btn btn-success' %>
<% end %>
note:
#software.platform_ids should be an array. If you are using SQLite, you have to convert string into array when you pull the data out. I tested it with SQLite and confirmed working as well. See my post for more detail.
This should be closer to what you were looking for:
<%= b.label(class: "checkbox-inline", :"data-value" => b.value) { b.check_box + b.text } %>
Try changing your _edit_word_form.html.erb like this
<%= form_for(#word) do |f| %>
<div class="field form-group">
<%= f.label(:title, "Word:") %><br>
<%= f.text_field(:title, id: "new_word", required: true, autofocus: true, class: "form-control") %>
</div>
<div class="field form-group">
<%= f.label(:description, "Definition:") %><br>
<%= f.text_area(:description, class: "form-control") %>
</div>
<%= f.fields_for :category do |category_form| %>
<% if current_user.word_list.categories.count > 0 %>
<div class="field form-group">
<%= category_form.label(:title, "Choose from existing Categories:") %><br>
<%= category_form.collection_check_boxes(:category_ids, current_user.word_list.categories.all, :id, :title) do |b| %>
<%= b.label(class: "checkbox-inline") { b.check_box + b.text } %>
<% end %>
</div>
<% end %>
<h4>AND/OR...</h4>
<div class="field form-group">
<%= category_form.label(:title, "Create and Use a New Category:") %><br>
<%= category_form.text_field(:title, class: "form-control") %>
</div>
<% end %>
<div class="actions">
<%= f.submit("Update!", class: "btn btn-block btn-primary btn-lg") %>
</div>
<% end %>
So user is editing a word from their word list, but you want to show checkboxes for all categories for all the words in their word list, checking those categories attached to the word being editing. Is that correct?
It looks like you're missing out the first parameter in #collection_check_boxes, which should be the object you call :category_ids on.
If the object is the user's word_list, then something like:
<%= category_form.collection_check_boxes(current_user.word_list, :category_ids, current_user.word_list.categories.all, :id, :title) do |b| %>
May not be the exact answer--I can't test it--but hope it gives you something to go on.
What's wrong
When you are calling category_form.collection_check_boxes(:category_ids, current_user.word_list.categories.all, :id, :title) within the fields_for :category, you are saying there is a method on #word.category called category_ids which will return the ids of the categories related to #word.category. The checkbox will be checked if there is a matching id both in category_ids results and in current_user.word_list.categories.all.
I don't think there is a #word.category or a #word.category.category_ids. I think there's #word.categories though.
How to fix it
That being said, my instinct tells me that you need to use something like:
<%= form_for(#word) do |f| %>
<div class="field form-group">
<%= f.label(:title, "Word:") %><br>
<%= f.text_field(:title, id: "new_word", required: true, autofocus: true, class: "form-control") %>
</div>
<div class="field form-group">
<%= f.label(:description, "Definition:") %><br>
<%= f.text_area(:description, class: "form-control") %>
</div>
<% if current_user.word_list.categories.count > 0 %>
<div class="field form-group">
<%= f.label(:categories, "Choose from existing Categories:") %><br>
<%= f.collection_check_boxes(:category_ids, current_user.word_list.categories.all, :id, :title) %>
</div>
<% end %>
<div class="actions">
<%= f.submit("Update!", class: "btn btn-block btn-primary btn-lg") %>
</div>
<% end %>
Note that I've moved the collection_check_boxes to the #word's form builder, as you are hoping to build the "categories" value for the current #word. I think this should be a step in the right direction anyway.

paperclip polymorphic nested multi file uploads

Not really any error messages, just no file uploaded!
Please help!!!!
everything get created and is fine apart from the file upload.
Models:
class Assets < ActiveRecord::Base
belongs_to :assetable, :polymorphic => true
delegate :url, :to => :attachment
attr_accessible :asset, :asset_file_name
end
class Video < ActiveRecord::Base
attr_accessible :body, :title, :url, :covers, :assets
has_many :covers, :as => :assetable, :class_name => "Video::Cover", :dependent => :destroy
accepts_nested_attributes_for :covers, :allow_destroy => true
class Video::Cover < Assets
has_attached_file :attachment, :styles => { :small => "300x0>", :large => "800x0>" }
end
end
video controller:
class VideosController < ApplicationController
#load_and_authorize_resource
# GET /videos
# GET /videos.xml
def index
#videos = Video.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #videos }
end
end
# GET /videos/1
# GET /videos/1.xml
def show
#video = Video.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #video }
end
end
# GET videos/new
# GET /videos/new.xml
def new
#video = Video.new
1.times do #video.covers.build end
#40.times do #video.images.build end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #video }
end
end
# GET /collections/1/edit
def edit
#video = Video.find(params[:id])
1.times do #video.covers.build end
#1.times do #video.images.build end
end
# POST /videos
# POST /videos.xml
def create
#video = Video.new(params[:video])
respond_to do |format|
if #video.save
format.html { redirect_to(#video, :notice => 'Video was successfully created.') }
format.xml { render :xml => #video, :status => :created, :location => #video }
else
format.html { render :action => "new" }
format.xml { render :xml => #video.errors, :status => :unprocessable_entity }
end
end
end
# PUT /videos/1
# PUT /videos/1.xml
def update
#video = Video.find(params[:id])
respond_to do |format|
if #video.update_attributes(params[:video])
format.html { redirect_to(#video, :notice => 'Video was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #video.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /videos/1
# DELETE /videos/1.xml
def destroy
#video = Video.find(params[:id])
#video.destroy
respond_to do |format|
format.html { redirect_to(videos_url) }
format.xml { head :ok }
end
end
end
Views:
form
<div id="form_bk">
<div id="field_left">
<%= form_for #video, :html => {:multipart => true} do |f| %>
<% if #video.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#video.errors.count, "error") %> prohibited this video from being saved:</h2>
<ul>
<% #video.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div id="cover">
<br />
<h2>Cover Image</h2>
<%= f.fields_for :covers do |cover_image| %>
<% if cover_image.object.new_record? %>
<p><%= cover_image.file_field :attachment %></p>
<% end %>
<% end %>
<%= f.fields_for :covers do |cover_image| %>
<% unless cover_image.object.new_record? %>
<br />
<p>
<%=image_tag cover_image.object.url(:small) %><br />
<br /> Delete cover <%= cover_image.check_box :_destroy %><br /><br />
</p>
<% end %>
<% end %>
</div>
<div id="form_right">
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div></div>
<div class="field">
<%= f.label :url %><br />
<%= f.text_area :url %>
</div></div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<br />
</div>
Index view
<% #videos.each do |video| %>
<div class="video">
<%- video.covers.each do |cover| %>
<div class="video_cover"><%=link_to image_tag (cover.url(:small)), video %></div>
<% end %>
<div class="video_title">
<%=link_to video.title, video %>
<%= video.body %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
<%= link_to 'Destroy', video, :confirm => 'Are you sure?', :method => :delete %>
</div>
</div>
<% end %>
<br /><br /><br />
<%= link_to 'New Video', new_video_path %>
<%= debug #videos %>

Resources