Ruby on rails - basic forms - undefined method `[]' for nil:NilClass - ruby-on-rails-3

I've problem with my "subscriber". It should just add an email to db with symptom active/inactive. It gaves me this error - undefined method `[]' for nil:NilClass
Extracted source (around line #2):
1: <div id="subscriber">
**2: <%= form_for #subscriber do |f| %>**
3: <%= f.label :email %>
4: <%= f.text_field :email %>
5: <%= f.hidden_field :active, :value => true %>
Here is model:
class Subscriber < ActiveRecord::Base
attr_accessor :email, :active
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
This is my view:
<div id="subscriber">
<%= form_for #subscriber do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.hidden_field :active, :value => true %>
<%= f.submit t('.submit') %>
<% end %>
</div>
Here is controller:
class SubscribersController < ApplicationController
def create
#subscriber = Subscriber.new(params[:subscriber])
if #subscriber.valid?
flash[:notice] = "Thx for subscription"
#subscriber.save
redirect_to root_url
else
render :action => 'new'
end
end
end
Here are routes:
resources :subscribers
I'm new with RoR, so if you need some more logs or info let me know. Thx alot.

Related

Rail authentication from scratch password confirmation isn't working

I'm following along Railscasts #250 Authentication from Scratch but have an issue where the Password Confirmation can be different from the Password and the user will still be created.
..model/dealer.rb:
class Dealer < ActiveRecord::Base
attr_accessor :password
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
def encrypt_password
if password.present?
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
end
..controllers/dealers_controller.rb
class DealersController < ApplicationController
def new
#dealer = Dealer.new
end
def create
#dealer = Dealer.new(dealer_params)
if #dealer.save
redirect_to root_url, :notice => "Signed Up!"
else
render "new"
end
end
private
def dealer_params
params.require(:dealer).permit(:email, :password)
end
end
..views/dealers/new.html/erb
<%= form_for #dealer do |f| %>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br>
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br>
<%= f.password_field :password_confirmation %>
</p>
<p class="button"><%= f.submit %></p>
Any ideas what I need to do for this to work? Two people in the comments of the Railscast had the same issue but no answer.
Have you tried to add password_confirmation to your allowed params like this:
def dealer_params
params.require(:dealer).permit(:email, :password, :password_confirmation)
end
If this doesn't help try to generate accessor for password_confirmation too:
attr_accessor :password, :password_confirmation

Rails 4 - comment.create saves :text but not :commenter

When I create a new comment the text saves fine but the commenter is not being saved. I have verified that the column for commenter exists and that the parameter is being passed. The field just isn't inserting into the table and I have no clue why.
Form:
<%= form_for #comment do |f| %>
<p>
<%= f.label :new_comment %>
<%= f.text_field :text %>
<%= hidden_field_tag :user_id, params[:user_id] %>
<%= hidden_field_tag :post_id, params[:id] %>
<%= f.submit "Comment" %>
</p>
<% end %>
Action:
def create
#user = User.find(params[:user_id])
#post = #user.posts.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:text, :commenter))
redirect_to show_post_path(#user, #post)
end
Add one more field in form which will pass commenter for comment
<%= form_for #comment do |f| %>
<p>
<%= f.label :new_comment %>
<%= f.text_field :text %>
<%= hidden_field_tag :user_id, params[:user_id] %>
<%= hidden_field_tag :post_id, params[:id] %>
<%= hidden_field_tag 'comment[commenter]', params[:user_id] %>
<%= f.submit "Comment" %>
</p>
<% end %>
OR
Change controller code to
def create
#user = User.find(params[:user_id])
#post = #user.posts.find(params[:post_id])
#comment = #post.comments.new(params[:comment].permit(:text, :commenter))
#comment.commenter = #user.id
#comment.save
redirect_to show_post_path(#user, #post)
end
I'm guessing you want your commenter_id in your form instead of user_id. Change your user_id line in your form to:
<%= hidden_field_tag :commenter_id, params[:commenter_id] %>
And then change the third line in your create function:
#comment = #post.comments.create(params[:comment].permit(:text, :commenter_id))
Have you check your association between User model and Comment Model?
in User model it should be has_many :comments and in Comment Model belongs_to :user

Using carrierwave to upload PDF causing rollback transaction error after submit

I'm using carrierwave to upload files/images to my application. I'm storing the files through Amazon AWS. The upload works great for images but when trying to add .PDF's I'm receiving a "rollback transaction" error in my server logs and I'm not sure why.
Started POST "/restaurants" for 127.0.0.1 at 2013-06-21 14:39:16 -0400
Processing by RestaurantsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"filAk5Jh++qmb7owXVgYin2C4nq2O+09gMeQV27gKeU=", "restaurant"=>{"name"=>"The Stumble Inn", "address"=>"", "phone"=>"", "description"=>"", "image"=>#<ActionDispatch::Http::UploadedFile:0x00000101da3f98 #original_filename="stumble.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"restaurant[image]\"; filename=\"stumble.jpg\"\r\nContent-Type: image/jpeg\r\n", #tempfile=#<File:/var/folders/6b/tq59gs0d1f7bp_zg41cf6fqm0000gn/T/RackMultipart20130621-40432-124zf2w>>, "remote_image_url"=>"", "menu"=>#<ActionDispatch::Http::UploadedFile:0x00000101da3d18 #original_filename="menu.pdf", #content_type="application/pdf", #headers="Content-Disposition: form-data; name=\"restaurant[menu]\"; filename=\"menu.pdf\"\r\nContent-Type: application/pdf\r\n", #tempfile=#<File:/var/folders/6b/tq59gs0d1f7bp_zg41cf6fqm0000gn/T/RackMultipart20130621-40432-3cwvjc>>}, "commit"=>"Create Restaurant"}
(0.2ms) begin transaction
(0.2ms) rollback transaction
Redirected to http://localhost:3000/restaurants
class MenuUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
# Choose what kind of storage to use for this uploader:
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
class Restaurant < ActiveRecord::Base
attr_accessible :address, :description, :name, :phone, :image, :remote_image_url, :menu
mount_uploader :image, ImageUploader
mount_uploader :menu, ImageUploader
end
new.html.erb
<h1>Add new restaurant</h1>
<%= form_for(#restaurant, :html => {:multipart => true}) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :phone %>
<%= f.text_field :phone %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.label :upload_image %>
<%= f.file_field :image %>
<%= f.label :remote_image_url, "or image URL:" %>
<%= f.text_field :remote_image_url %>
<%= f.label :upload_menu %>
<%= f.file_field :menu %><br/><br/>
<%= f.submit "Create Restaurant" %>
<% end %>
class RestaurantsController < ApplicationController
def new
#restaurant = Restaurant.new
end
def create
#restaurant = Restaurant.new(params[:restaurant])
#restaurant.save
redirect_to restaurants_path
end
I realized that I had a type in the Restaurant model.
mount_uploader :menu, ImageUploader
should be:
mount_uploader :menu, MenuUploader

How to access attributes in a partial of a nested rails form?

I want to use the boolean attribute is_white from my inner_object to switch between html code in the the partial _inner_object_form_fields. This is my attempt.
<%= form_for #outer_object do |f| %>
<%= f.fields_for :inner_object do |builder| %>
<%= render :partial => "inner_object_form_fields", :locals => { :f => builder } %>
<% end %>
<% end %>
This is my attempt of the partial _inner_object_form_fields.
<% if f.is_white == true %>
<%= f.label(:name, "White") %>
<% else %>
<%= f.label(:name, "Black") %>
<% end %>
This is the migration file of InnerObjects.
class InnerObjects < ActiveRecord::Migration
def self.up
create_table :inner_objects do |t|
t.string "name"
t.boolean "is_white", :default => true
t.timestamps
end
end
def self.down
drop_table :inner_objects
end
end
I found a similar question but could not retrieve an answer for me.
The question is: How can access the attribut is_white? My example does NOT work.
Try
<% if f.object.is_white == true %>
Seem to remember you could access the object this way (not 100% sure though ;)
Is it because f.is_white is based on a blank object in the partial? Try
<%= form_for #outer_object do |f| %>
<%= f.fields_for f.inner_object do |builder| %>
<%= render :partial => "inner_object_form_fields", :locals => { :f => builder } %>
<% end %>
<% end %>
That way it's referencing the attached object and any state you've created.
Even one step further would be to do something like this:
<%= f.fields_for f.inner_object do |builder| %>
<%= render :partial => "inner_object_form_fields", :locals => { :f => builder, :inner_object => builder.object } %>
<% end %>
Then you can do.
<% if inner_object.is_white == true %>
This way your partials code looks a little cleaner.

How do you pass rails 3 forms params into an array?

I have a nested form (using accepts_nested_attributes_for in respective models):
<%= form_for(:technician, :url => {:controller => 'pos', :action => 'create_ticket'}) do |f| %>
<%= f.fields_for :service do |s| %>
<%= s.text_field :name %>
<%= s.text_field :name %>
<%= s.text_field :name %>
<%= s.text_field :name %>
<% end %>
<% end %>
This works fine if I only have one s.text_field. But once I add additional text_fields, it doesn't run properly. If you look at the source code, the id and name are the same for all six?
How do I put these params into an array? [so that I can isolate them like this:]
service1 = Service.named(params[:technician][:service][1][:name])
(I've tried the method described on railscasts episode 192, but it didn't work either).
After hours of trial and error, I've hacked something that works (but please let me know if you know a better, more eloquent way):
in view:
<%= form_for(:technician, :url => {:controller => 'pos', :action => 'create_ticket'}) do |f| %>
<% for #i in 1..6 do %>
<%= f.fields_for "services[#{#i}]" do |s| %>
<% end %>
<% end %>
<% end %>
in controller:
for i in 1..6 do
#service = Service.named(params[:technician][:services][i.to_s][:name]).first
end
make sure you turn i into string