Another newb question. A Band has_many Albums. I'm getting the error:
ActiveRecord::AssociationTypeMismatch (Band(#70076964285020) expected,
got "1" which is an instance of String(#12787800)):
app/controllers/albums_controller.rb:20:in `create'
... which is the build line in #create
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
binding.pry
#band = Band.find(params[:album][:band].to_i)
authorize #band, :admin?
#album = #band.albums.build(album_params)
if #album.save
#albums = #band.albums
##eps = #band.eps
#songs = #band.songs
respond_to do |format|
format.js
end
else
#fail = "fail"
respond_to do |format|
format.js
end
end
end
def album_params
params.require(:album).permit(:band, :album_name, :album_release_date, :etc)
end
the form:
<%=simple_form_for(#album, remote: true, :authenticity_token => true, format: :js) do |f| %>
<%= f.hidden_field :band, :value => #band.id %>
<%= f.input :album_name %>
<%= f.input :album_release_date %>
<%= f.input :etc %>
<div id="albumsubmit">
<div class="form-actions">
<%= f.button :submit, "Create Album", class: "btn btn-primary" %>
</div>
</div>
schema
create_table "albums", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "band_id"
t.string "album_name"
t.string "album_release_date"
t.index ["band_id"], name: "index_albums_on_band_id"
end
when you passing to save method param with that have has_many Association he expect the instance of "band", just set the param name to band_id
here:
<%= f.hidden_field :band, :value => #band.id %>
to:
<%= f.hidden_field :band_id, :value => #band.id %>
and here:
params.require(:album).permit(:band, :album_name, :album_release_date, :etc)
to:
params.require(:album).permit(:band_id, :album_name, :album_release_date, :etc)
Ok, so I integrated money-rails gem into my basic calculating app ...
When I try to run it now, I get this error:
ActiveRecord::StatementInvalid in TippiesController#create
and this line underneath it:
PG::NotNullViolation: ERROR: null value in column "tip" violates not-null constraint DETAIL: Failing row contains (37, null, null, 2017-03-10 07:47:36.152504, 2017-03-10 07:47:36.152504, 3300, USD, 10, USD). : INSERT INTO "tippies" ("created_at", "updated_at", "cost_cents", "tip_cents") VALUES ($1, $2, $3, $4) RETURNING "id"" ...
So, I thought this meant that it was generating this because my my model stipulates validates :tip, presence: true ... so I commented it out, but still receive this error.
Not sure how to sort it out. Any help in figuring it out would be appreciated.
Current Model
class Tippy < ApplicationRecord
validates :tip_cents, presence: true
validates :cost_cents, presence: true
monetize :tip_cents
monetize :cost_cents
TIP_CHOICES = { "10%" => ".10", "20%" => ".20", "30%" => ".30", "40%" => ".40", "50%" => ".50",
"60%" => ".60", "70%" => ".70", "80%" => ".80", "90%" => ".90" }
def calculation_of_total_cost
cost_cents + (tip_cents * cost_cents)
end
end
Current Controller
class TippiesController < ApplicationController
before_action :set_tippy, only: [:show, :edit, :update, :destroy]
# GET /tippies
# GET /tippies.json
def index
#tippies = Tippy.all
end
# GET /tippies/1
# GET /tippies/1.json
def show
##calculation_of_total_cost
end
# GET /tippies/new
def new
#tippy = Tippy.new
end
# GET /tippies/1/edit
def edit
end
# POST /tippies
# POST /tippies.json
def create
#tippy = Tippy.new(tippy_params)
respond_to do |format|
if #tippy.save
format.html { redirect_to #tippy, notice: 'Tippy was successfully created.' }
format.json { render :show, status: :created, location: #tippy }
else
format.html { render :new }
format.json { render json: #tippy.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tippies/1
# PATCH/PUT /tippies/1.json
def update
respond_to do |format|
if #tippy.update(tippy_params)
format.html { redirect_to #tippy, notice: 'Tippy was successfully updated.' }
format.json { render :show, status: :ok, location: #tippy }
else
format.html { render :edit }
format.json { render json: #tippy.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tippies/1
# DELETE /tippies/1.json
def destroy
#tippy.destroy
respond_to do |format|
format.html { redirect_to tippies_url, notice: 'Tippy was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_tippy
#tippy = Tippy.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def tippy_params
params.require(:tippy).permit(:tip, :cost, :tip_cents, :tip_currency, :cost_cents, :cost_currency)
end
end
Migrated Monetize File
class MonetizeTippy < ActiveRecord::Migration[5.0]
def change
add_monetize :tippies, :cost
add_monetize :tippies, :tip
end
end
Schema
ActiveRecord::Schema.define(version: 20170310070749) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "tippies", force: :cascade do |t|
t.float "tip", null: false
t.decimal "cost", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "cost_cents", default: 0, null: false
t.string "cost_currency", default: "USD", null: false
t.integer "tip_cents", default: 0, null: false
t.string "tip_currency", default: "USD", null: false
end
end
Show.html.erb (this page pops up after the home page which is new action
<br/><br/>
<h1 class="text-center">Your Total Cost</h1>
<br/><br />
<table class="table table-striped">
<tr>
<td>
Cost of Your Meal:
</td>
<td>
<%= humanized_money_with_symbol #tippy.cost_cents %>
</td>
</tr>
<tr>
<td>
Tip You Picked:
</td>
<td>
<%= number_to_percentage(#tippy.tip_cents * 100, format: "%n%", precision: 0) %>
</td>
</tr>
<tr>
<td>
The Total Cost:
</td>
<td>
<%= humanized_money_with_symbol #tippy.calculation_of_total_cost %>
</td>
</tr>
</table>
new.html.erb
<br /><br />
<h1 class="text-center">Calculate Your Tip!</h1>
<%= render 'form', tippy: #tippy %>
_form.html.erb
<%= form_for(tippy, :html => {'class' => "form-horizontal"}) do |f| %>
<% if tippy.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(tippy.errors.count, "error") %> prohibited this tippy from being saved:</h2>
<ul>
<% tippy.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field form-group">
<%= f.label :cost_of_your_meal, class: "control-label" %>
<%= f.text_field :cost, class: "form-control" %>
</div>
<div class="field form-group">
<%= f.label :pick_your_tip, class: "control-label" %>
<%= f.select(:tip, Tippy::TIP_CHOICES, class: "form-control") %>
</div>
<div class="actions">
<%= f.submit class: "btn btn-primary btn-lg btn-block" %>
</div>
<% end %>
This error comes from the database, not Rails.
In the migration where the tip column gets added, it will look something like this:
t.float :tip, null: false
This translates to a NOT NULL constraint in your SQL schema.
A database constraint and a validation do not serve the same purpose: the former is for definitely preventing incorrect data from being persisted, whereas the latter is an easy way to communicate errors back to your users through the automatically added ActiveModel::Errors object.
To solve your problem you have to add another migration and make tip nullable again (and maybe provide an appropriate default value):
change_column :tippies, :tip, :float, null: true, default: 0
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.
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 %>