Rails form not passing image with carrierwave - ruby-on-rails

I've currently got an upload form that takes an epub file, parses it using epubinfo and then displays in another form to validate the information we're extracting is correct. We then submit this new upload from this form.
This first form (upload.html.erb) seems to work exactly as I'd expect, extracting all the information I required, including the cover image and displays it appropriately in the edit/verification form (new.html.erb). However, the issue lies in this second form (new). Upon posting it doesn't retain the cover image that was displayed, instead not saving anything, even though any other changed (or unchanged) data in this form posts just as it should.
To note, when the upload form posts, public/tmp gets two files, the epub and the png, and upon posting the new form, the epub tmp goes away and gets put into public, however the png stays in public/tmp.
Ruby 2.1.1p76
Rails 4.1
CarrierWave 0.10.0
/views/pages/upload.html.erb
<%= form_for Book.new, :url => new_book_path do |f| %>
<div class="form-group">
<%= f.label :book, "Upload an epub" %>
<%= f.file_field :book, class: "form-control" %>
<%= f.hidden_field :book_cache %>
</div>
<br />
<div class="form-group">
<%= f.button "Upload", class: "btn btn-primary", data: {disable_with: "Uploading..."} %>
</div>
<% end %>
/app/controllers/books_controller.rb (somewhat sanitized):
class BooksController < ApplicationController
before_action :redirect_to_book, only: [:index]
before_action :set_book, only: [:show, :edit, :update, :destroy, :download]
before_action :is_mod, only: [:edit, :update, :destroy]
def create
#books = Book.new(book_params)
if #books.author.nil? && book_params[:author_name].present?
#books.author = Author.where(name: book_params[:author_name]).first_or_create
end
if #books.series.nil? && book_params[:series_name].present?
#books.series = Series.where(name: book_params[:series_name]).first_or_create
end
if book_params[:is_public].present?
else
#books.is_public == true
end
if #books.save
redirect_to book_path(#books), success: "The book was successfully saved!"
else
redirect_to new_book_path
end
end
def new
#authors = Author.all
#series = Series.all
#books = Book.new(book_params)
#books.extract_epub_info
end
private
def set_book
#books = Book.find(params[:id])
rescue ActiveRecord::RecordNotFound
redirect_to "/404"
end
def redirect_to_book
redirect_to book_path(params[:book_id]) if params[:book_id]
end
def book_params
params.require(:book).permit(:book, :cover, :title, :isbn, :summary, :is_public, :series_nbr, :author_id, :author_name, :series_id, :series_name, :tag_list, :book_cache)
end
def is_mod
unless current_mod
redirect_to book_path, error: "You're not allowed to edit books."
end
end
end
/app/uploaders/book_uploader.rb
class BookUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{mounted_as}"
end
def filename
"#{model.id}.epub"
end
end
/app/uploaders/cover_uploader.rb
class CoverUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{mounted_as}"
end
def filename
"#{model.id}.png"
end
end
/app/models/book.rb
class Book < ActiveRecord::Base
belongs_to :author
belongs_to :series
has_many :downloads
has_many :flags
has_many :ratings
has_many :raters, :through => :ratings, :source => :users
validates :title, :author_id, presence: true
attr_accessor :author_name, :series_name
acts_as_taggable
scope :public_books, ->{ where(is_public: true) }
mount_uploader :book, BookUploader
# validates_presence_of :book
mount_uploader :cover, CoverUploader
# validates_presence_of :cover
searchable do
text :title
text :summary
text :isbn
integer :is_public
end
def epub
#epub ||= EPUBInfo.get(book.file.path)
end
def extract_epub_info
if epub.creators.first.name.include? ","
self.author = Author.where(name: epub.creators.first.name).first_or_create
else
parts = epub.creators.first.name.split
first = parts.first
last = parts[1..-1].join(" ")
self.author = Author.where(name: "#{last}, #{first}").first_or_create
end
self.title = epub.titles.first
self.summary = epub.description
self.is_public = true
self.isbn = epub.identifiers.find{ |i| i.scheme == "ISBN" }.try(:identifier)
if epub.cover.present?
self.cover = epub.cover.tempfile
else
end
end
end
And the edit form that displays the cover appropriately but doesn't post when you submit the form.
/views/books/new.html.erb:
<%= form_for #books, url: books_path, html: {multipart: true} do |f| %>
<% if #books.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#books.errors.count, "error") %> prohibited this author from being saved:</h2>
<ul>
<% #books.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<br/><br/>
<div class="alert alert-warning">
<strong>Please validate that all of this information is correct before saving the book!</strong>
</div>
<br/>
<% if #books.cover.present? %>
<div align="center">
<%= image_tag #books.cover %>
</div>
<% end %>
<div class="form-group">
<%= f.label :title %>
<%= f.text_field :title, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :author %>
<%= f.collection_select(:author_id, #authors.order("name ASC"), :id, :name, {:include_blank => true} ) %>
OR New Author Name:
<%= f.text_field :author_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :isbn %>
<%= f.text_field :isbn, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :summary %>
<%= f.text_area :summary, class: "form-control", size: "20x10" %>
</div>
<div class="form-group">
<%= f.label :series_nbr %>
<%= f.text_field :series_nbr, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :series %>
<%= f.collection_select(:series_id, #series.order("name ASC"), :id, :name, {:include_blank => true} ) %>
OR New Series Name:
<%= f.text_field :series_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :tag_list %>
<%= f.text_field :tag_list, class: "form-control" %>
</div>
<%= f.hidden_field :book_cache %>
<div class="form-group">
<%= f.label :cover, "Upload a cover" %>
<%= f.file_field :cover, class: "form-control" %>
</div>
<br/>
<div class="form-group">
<%= f.hidden_field :is_public, :value => "1" %>
<%= f.submit class: "btn btn-primary", data: { confirm: "Are you sure all of this information is correct?\rYou will not be able to edit it later." } %>
</div>
<% end %>
EDIT for routes 11/2 # 9:20ET
routes.rb
App::Application.routes.draw do
root "pages#home"
# All pages
get "browse" => "books"
get "browse/new" => "books#newest"
get "browse/popular" => "books#popular"
get "browse/random" => "books#random"
get "faq" => "pages#faq"
get "empowerment" => "pages#empowerment"
get "legal" => "pages#legal"
get "pages/catalog"
get "search" => "search#search"
get "search/search"
get "upload" => "pages#upload"
get "download" => "pages#download"
get "dmca" => "pages#dmca"
# Catalog Routes
get "catalog" => "catalog#index", defaults: {format: :atom}
get "catalog/search" => "catalog#search", defaults: {format: :atom}
%w{ newest popular random author title serie tag }.each do |section|
get "catalog/#{section}", controller: :catalog, action: section, defaults: {format: :atom}
end
get "catalog/author/:id" => "catalog#authored_by", defaults: {format: :atom}
get "catalog/tag/:tag" => "catalog#tagged", defaults: {format: :atom}
# Normal Model stuff
resources :authors
resources :series
resources :books do
collection do
get "tagged/:tag", action: :tagged, as: :tagged
post "new", action: :new, as: :new_book
end
member do
get :download
end
end
resources :tags
# Stuff for Mods and management
devise_for :mods
namespace "admin" do
resources :mods
end
devise_scope :mod do
get "mods" => "devise/sessions#new"
end
# Lists for dropdowns
get "authorlist" => "books#authorlist"
get "serieslist" => "books#serieslist"
get "taglist" => "books#taglist"
# Let's be nice and support old urls.
get "book/show/id/:id" => "books#show"
get "serie/:id" => "series#show"
get "author/:id" => "authors#show"
get "browse/author/:id" => "authors#show"
end
I'm not sure what else would be needed. I feel that what I'm missing is simple, but after staring at it for so long I've just stopped making any progress. I know that the cover image shows up in new.html.erb because it displays in the image_tag in the form, however upon post it doesn't save the param.
Halp! :(

/views/pages/upload.html.erb -- missing multipart: true
<%= form_for Book.new, html: { multipart: true } do |f| %>
I don't think you need to supply the url argument unless you've set up your routes/models incorrectly. You should change this in your other forms as well.
/app/controllers/books_controller.rb
You're completely missing edit/update methods. Is this by design? Why? Is this why you're supplying the url option in the forms? This promotes confusion.
Have you viewed the contents of book_params to see if the image data is being received correctly? What about checking to see if the actual image files have been created? If they are created, perhaps they're just not accessible (check file permissions).
FURTHER EDIT: I can't determine how things are routed based on what you've shown. Please show your routes as well, and clearly describe which actions result in the unwanted consequences.
i.e., "I want to create a new book, but the uploaded image isn't saved" (meaning it doesn't exist in the database and there's no actual image anywhere on the disk).
or
"I can create a book and save the image, but upon viewing the EDIT page, the image doesn't show up"

Related

has_many join form with collection checkboxes not saving more than one checkbox value

I am working on a form for a editorial calendar app. I have two things going out that are pretty similar and not working.
Working with 3 models: Platforms, Posts and Calendars. They are join tables. Platform <=> Post, Post <=> Calendars
Post/new & Post/edit form:
<div class="container">
<div class="form-field">
<%= form_for #post do |f| %>
<%= f.label :title %>
<%= f.text_field :title, required: true %> <br>
Title is required.
</div>
<div class="form-field">
<%= f.label :content%>
<%= f.text_area :content%>
</div>
<div class="form-field">
<%= f.label :link %>
<%= f.text_field :link %>
</div>
<div class="file-field">
<%= f.label :picture%>
<%= f.file_field :picture, id: :post_picture%>
</div>
<div class="file-field">
<%= f.label :finalized %>
<%= f.radio_button :finalized , true%>
<%= f.label :finalized, "Yes" %>
<%= f.radio_button :finalized, false %>
<%= f.label :finalized, "No" %>
</div>
<%= f.hidden_field :user_id %> <br>
<div class="form-field">
<%= f.fields_for :platform_attributes do |platform| %>
<%= platform.label :platform, "Social Platforms"%>
<%= platform.collection_check_boxes :platform_ids, Platform.all, :id, :name %> <br> <br>
</div>
<div>
<h4> Or Create a new platform: </h4>
<%= platform.label :platform, 'New Platform'%>
<%= platform.text_field :name%> <br> <br>
</div>
<% end %>
<%= f.submit%>
<% end %>
</div>
My post controller is handling the checkboxes issue, and the "schedule post" issue. It will only allow me to schedule for one calendar, and it does not save the updates and add additional calendars.
Posts Controller:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :schedule_post, :destroy]
def new
#posts = current_user.posts.select {|p| p.persisted?}
#post = current_user.posts.build
#platforms = Platform.all
end
def edit
#calendars = current_user.calendars
#platforms = Platform.all
end
def create
#post = current_user.posts.build(post_params)
if #post.save
redirect_to post_path(#post)
else
redirect_to new_post_path
end
end
def update
#post.update(post_params)
if #post.save
redirect_to post_path(#post), notice: 'Your post has been updated.'
else
redirect_to edit_post_path(#post)
end
end
def schedule_post
#calendar_post = CalendarPost.new(calendar_post_params)
if #calendar_post.save
binding.pry
redirect_to post_path(#post)
else
render 'show'
end
end
private
def set_post
#post = Post.find(params[:id])
end
def set_calendars
#calendars = current_user.calendars
end
def post_params
params.require(:post).permit(:title, :content, :link, :finalized, :picture, :user_id, :platform_attributes => [:platform_ids, :name])
end
def calendar_post_params
params.require(:calendar_post).permit(:post_id, :calendar_id, :date, :time)
end
end
I want the user to be able to add a post to multiple platforms and multiple calendars because of the versatility of what someone may need.
I also have my setter in my Post model.
class Post < ApplicationRecord
has_many :calendar_posts
has_many :calendars, through: :calendar_posts
has_many :platform_posts
has_many :platforms, through: :platform_posts
belongs_to :user
def platform_attributes=(platform_attributes)
if platform_attributes['platform_ids']
platform_attributes.platform_ids.each do |id|
platform = Platform.find(id: id)
self.platforms << platform
end
end
if platform_attributes['name'] != ""
platform = Platform.find_or_create_by(name: platform_attributes['name'])
self.platforms << platform
end
end
thoughts? why are they not saving to more than one calendar or more than one platform if they choose to have more than one?
Here is the updated code... and more of what I know about these changes and what is happening.
My submit button is not working for some odd reason on my form, so I'm trying to get the params submitted but it won't even route to give me params even if I raise them, nothing is happening.
On the form you can choose checkboxes or add in a platform. If you add in a platform it creates that one but it does not also save the other ones you selected. If you go to edit the post, and click submit with changes, no page loads at all and nothing is happening in log. It's just idle.
<%= f.fields_for :platform_attributes do |platform| %>
assumes you are creating one platform... it says "these are the fields for this platform"
but platform_ids is intended to be a selection of a set of platforms... and probably should be outside of the fields_for section (which should only surround the name field).
try something like the following:
<div class="form-field">
<%= f.label :platform_ids, "Social Platforms"%>
<%= f.collection_check_boxes :platform_ids, Platform.all, :id, :name %> <br> <br>
</div>
<div>
<%= f.fields_for :platform_attributes do |platform| %>
<h4> Or Create a new platform: </h4>
<%= platform.label :name, 'New Platform'%>
<%= platform.text_field :name%> <br> <br>
<% end %>
<%# end fields_for %>
</div>
Also you'll need to update permit/require appropriately eg
def post_params
params.require(:post).permit(:title, :content, :link, :finalized, :picture, :user_id, :platform_ids, :platform_attributes => [:name])
end
Note: not tested - bugs are left as an exercise for the reader ;)

Rails: File to Upload does not get passed from Form to the controller

This is the Form. All of the fields get passed (and saved) except the one containing the File.
I have checked that using the
render plain: params[:article].inspect method
giving out this (I have entered the value "n" for all fields):
{"country"=>"n", "region"=>"n", "town"=>"n", "street"=>"n", "company"=>"n", "title"=>"n", "content"=>"n"}
I am leaving out superfluous fields here to make the Form shorter:
<%= form_for(#article, html: { multipart: true }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :country %>
<%= f.text_field :country, :required => true,
placeholder: "enter country" %>
</div>
<%= f.label :content %>
<%= f.text_field :content, :required => true, placeholder: "town..." %>
</div>
</div>
</div>
</div>
<span class="picture">
<%= form_for #article, html: { multipart: true } do |f| %>
<%= f.text_field :title %>
<%= fields_for :pictures do |ff| %>
<%= ff.file_field :picture %>
<% end %>
<% end %>
</div>
I have also tried the slight variation here, but no change
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for
The create method at the Controller is like this:
def create
#article = current_user.articles.build(article_params)
if #article.save
flash[:success] = "Article created!"
redirect_to root_url
else
render 'articles/new'
end
end
and yes, the new method in the Articles controller, is like I was indicated by peers here:
def new
#article = current_user.articles.build
#article.pictures.build
end
The Article Model
class Article < ActiveRecord::Base
belongs_to :user
has_many :pictures
accepts_nested_attributes_for :pictures, allow_destroy: true
And the pictures Model
class Picture < ActiveRecord::Base
belongs_to :article
mount_uploader :picture, PictureUploader
end
Change your <%= fields_for :pictures do |ff| %> to <%= f.fields_for :pictures do |ff| %>

trouble with rails rendering partial and finding custom controller

Background: I would like to make a team and have the user verify the address of that team before the team is saved.
In my application I have a form that creates a team when the form is submitted. Within this form I have a partial that is suppose to render with a field location. When the user clicks submit within the partial form the location field (within the partial form and not the create team form) should go to the verify_Address action within the teams_controller. Instead of this happening I get an error when I load the page.
The error on pageload:
undefined local variable or method `verify_address' for #<#<Class:0x000001063ec8d8>:0x00000104555af0>
with this line highlighted: <%= form_for :team, url: verify_address, method: :post, remote:true do |f|%>
below are my files within the app.
route.rb file:
resources :users, :path => :captains, :as => :captains, :controller => "captains" do
resources :teams, :only => [:new, :create, :edit, :update, :destroy], controller: 'captains/teams'
end
resources :teams, :only => [:index, :show] do
resources :users, :path => :teammates, :as => :teammates, :controller => "teammates"
end
put 'captains/:id/teams/verify_address' => "teams#verify_address",as: 'verify_address'
get 'captains/:id/teams/verify_address' => "teams#verify_address"
controller/captains/teams_controller.rb:
class Captains::TeamsController < ApplicationController
respond_to :html, :js
def new
#team = Team.new
#captain = current_user
end
def verify_address
#address = params[:team][:location]
#validate_address = Team.validate_address(#address)
end
def create
#captain = current_user.id
#team = Team.create(
:name => params[:team][:name],
:location => params[:team][:location],
:sport => params[:team][:sport],
:captain_id => #captain,
:avatar => params[:team][:avatar]
)
if #team.present?
redirect_to #team # show view for team
end
binding.pry
end
end
the partial views/captains/teams/_verify_address.html.erb:
<%= form_for :team, url: verify_address, method: :post, remote:true do |f|%>
<div class = "form-group">
<%= f.label :location %>
<%= f.text_field :location, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.submit "Verify address" ,class: 'btn btn-success' ,id: 'verify_address' %>
</div>
<% end %>
the main form views/captains/teams/new.html.erb:
<%= form_for :team, url: captain_teams_path(#captain, #team), method: :post do |f|
%>
<div class="form-group">
<%= f.label :avatar %>
<%= f.file_field :avatar %>
<%= f.hidden_field :avatar_cache %>
</div>
<div class = "form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.label :sport %>
<%= f.text_field :sport, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.label :location %>
<%= f.text_field :location, class: 'form-control', placeholder: "Enter wiki title", id:'team_title' %>
</div>
<div class = "form-group">
<%= f.submit class: 'btn btn-success' ,id: 'team_role_submit' %>
</div>
<% end %>
</div>
<%= render partial: "/captains/teams/verify_address", locals: { address: #address, validate_address: #validate_address}%>
</div>
Creating a custom route verify_address generates verify_address_path url helper, which you should use in your form.

Rails 4 custom controller action error - "Couldn't find 'model' without an ID"

I'm trying to add a custom create action for my Book model, but i keep ending up with a "Couldn't find Book without an ID".
routes.rb:
Books::Application.routes.draw do
resources :books
resources :books do
collection do
post 'create_new_record', :action => :create_new_record
end
end
match 'create_new_record' => 'books#create_new_record', via: [:post]
The relevant controller action:
def create_new_record
#book = Book.new(book_params)
respond_to do |format|
if #book.save
format.html { redirect_to #book, notice: 'New book record created.' }
end
end
end
And my form (in new.html.erb). I'm looping through results that i get from goodreads.com.
<% #book_search.results.work.each do |stuff| %>
<%= form_for(#book, :url => create_new_record_books_path) do |f| %>
<div class="field">
<%= f.label :author %><br>
<%= f.text_field :author, :value => stuff.best_book.author.name %>
</div>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title, :value => stuff.best_book.title %>
</div>
<div class="field">
<%= f.label :isbn %><br>
<%= f.text_field :isbn, :value => stuff.best_book.isbn %>
</div>
<div class="field">
<%= f.label :image %><br>
<%= f.text_field :image, :value => stuff.best_book.image_url %>
</div>
<div class="field">
<%= f.label :bookid %><br>
<%= f.text_field :bookid, :value => stuff.best_book.id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<hr>
<% end %>
The error i get when submitting the form is:
ActiveRecord::RecordNotFound in BooksController#create_new_record
on the callback
def set_book
#book = Book.find(params[:id])
end
I'm pretty much stumped now, my understanding is that it doesn't even reach the action, but instead looks for a book id that doesn't exist?
Thank you!
If you use before_filter so you don't pass an id to create action. Call your before filter the following way:
before_filter :set_book, except: [:index, :new, :create]
If you use model callback, params is unavailable in the model so pass the id some other way, for example via attr_accessor.
use #book = Book.where(id: params[:id]).first

Rails 4 strong params and nested form

I'm building a simple app (Ruby 2.0.0 and Rails 4) where a user can create a project and for each project create multiple screens. When creating a screen the user can upload a screenshot, that refer to a its own model (I do this to handle multiple versions of the same screen).
When creating the screen, the screenshot doesn't seem to be created because of a permission problem. Here's the server log:
Processing by ScreensController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"kezaGADsaLmY/+zozgbjEe5UfdeqRPg58FCf1qzfHxY=", "screen"=>{"project_id"=>"24", "name"=>"Billing", "description"=>"This is the page where a user will enter their credit card information", "screenshot"=>{"image"=># <ActionDispatch::Http::UploadedFile:0x007fcdce25b2c0 #tempfile=#<Tempfile:/var/folders/pv/srwrv0qj35b0hsxkt42l_z500000gn/T/RackMultipart20131007-91790-tewse9>, #original_filename="fb-banner.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"screen[screenshot][image]\"; filename=\"fb-banner.png\"\r\nContent-Type: image/png\r\n">}}, "commit"=>"Create Screen"}
Unpermitted parameters: screenshot
These are my models:
Screen
class Screen < ActiveRecord::Base
belongs_to :project
has_many :screenshots
validates :name, presence: true
accepts_nested_attributes_for :screenshots
end
Screenshot
class Screenshot < ActiveRecord::Base
belongs_to :screen
end
This is my screens_controller:
class ScreensController < ApplicationController
before_action :set_screen, only: [:show, :edit, :update, :destroy]
def index
#screens = Screen.all
end
def show
end
def new
#screen = Screen.new(:project_id => params[:project_id])
#screen.screenshot.build
end
def edit
end
def create
#screen = Screen.create(screen_params)
if #screen.save
flash[:notice] = "A new screen has been added to this project"
redirect_to [#screen.project]
else
render :action => 'new'
end
end
def update
#screen = Screen.find(params[:id])
if #screen.update_attributes(screen_params)
flash[:notice] = "The screen has been successfully updated"
redirect_to [#screen.project]
else
render :action => 'edit'
end
end
def destroy
#screen = Screen.find(params[:id])
#screen.destroy
flash[:notice] = "Successfully destroyed screen"
redirect_to [#screen.project]
end
private
def set_screen
#screen = Screen.find(params[:id])
end
def screen_params
params.require(:screen).permit(:project_id, :name, :description, screenshot_attributes: [ :id, :screen_id, :image, :version ])
end
end
And finally this is the form:
<%= form_for #screen, :html => { :multipart => true } do |f| %>
<% if #screen.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#screen.errors.count, "error") %> prohibited this screen from being saved:</h2>
<ul>
<% #screen.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.hidden_field :project_id %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<%= f.fields_for :screenshot do |s| %>
<%= s.hidden_field :screen_id, :value => #screen.id %>
<%= s.hidden_field :version, :value => "1" %>
<%= s.label :image %><br>
<%= s.file_field :image %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I hope this is enough to help me spot the problem. I'm a newbie when it comes to programming, so any help is more than welcome.
I recently worked through something similar, and this is what seemed to work...
Change your fields_for to plural:
<%= f.fields_for :screenshots do |s| %>
And also, make your params
def screen_params
params.require(:screen).permit(:project_id, :name, :description, screenshots_attributes: [ :id, :screen_id, :image, :version ])
end
Also, you need to update your new action to make screenshots plural, like so:
def new
#screen = Screen.new(:project_id => params[:project_id])
#screen.screenshots.build
end

Resources