Currently implementing Threaded Messaging. via RailsCast
I've installed the Ancestry gem, however all messages that I create are parents. ie.) Ancestry = nil
Even after passing my parent:id to new action
Message Controller
def index
#message = Message.new
#user = current_user
#sent_messages = current_user.sent_messages
#received_messages = current_user.received_messages
end
def new
#message = Message.new
#message.parent_id = params[:parent_id]
end
Index.html
<% for incoming in #received_messages %>
<%= render partial: "message", locals: {incoming: incoming} %>
_message.html.erb
</div>
<%= link_to "Reply", new_message_path(:parent_id => incoming) ,class: "regular" %>
</div>
new.html.erb
<%= form_for #message do |f| %>
<p>
To:<br />
<%= f.hidden_field :parent_id %>
<%= f.hidden_field :recipient, :value => (#message.parent.sender.name) %>
</p>
<p>
Message<br />
<%= f.text_area :body %>
</p>
<p>
<%= submit_tag "Send Threaded Reply" %>
</p>
<% end %>
Message.rb
class Message < ActiveRecord::Base
attr_accessible :recipient, :subject, :body, :parent_id
has_ancestry
end
My console after creating a message:
Key point - I'm passing the parent_id (144) in Message however ancestry still passes as nil.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gKVr06oT+6OcAERHAzSX79vTlJLniofmEOjZPdZmfwM=", "message"=>{**"parent_id"=>"114"**, "recipient"=>"Rach Miller", "body"=>"meh and more meh"}, "commit"=>"Send Threaded Reply"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 17 LIMIT 1
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."name" = 'Rach Miller' LIMIT 1
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "messages" ("ancestry", "body", "created_at", "read_at", "recipient_deleted", "recipient_id", "sender_deleted", "sender_id", "subject", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id" [["ancestry", nil], ["body", "meh and more meh"], ["created_at", Tue, 20 Aug 2013 03:14:15 UTC +00:00], ["read_at", nil], ["recipient_deleted", false], ["recipient_id", 18], ["sender_deleted", false], ["sender_id", 17], ["subject", nil], ["updated_at", Tue, 20 Aug 2013 03:14:15 UTC +00:00]]
After Bigxiang's comment, I decided to take a look at my create function.
I have been passing my params individually, So using
#message.parent_id = params[:message][:parent_id] worked for me
Cheers
Related
I'm using devise in rails, and I'm trying to create a second registration path, the default registration path for users (which works perfectly), and a second registration path whereby a user registers and creates a project in a single action as a "Getting Started" action (Think Freelancer.com or any marketplace whereby non-users can register and create their first project in one action).
I've gone through so many threads but they all seem to want to replace the existing registration action. I want to keep the existing registration action and either add a getting_started_new and getting_started_create actions to the existing User::Registration controller, or create a new GettingStarted Controller with methods for new and create that would then allow the nested form (for a user and their new project).
My latest iteration looks something like this:
routes.rb
devise_for :users
resources :users do
resources :projects
end
devise_scope :user do
get "getting_started" =>'getting_started#new'
post "getting_started" =>'getting_started#create'
end
getting_started_controller.rb
class GettingStartedController < Devise::RegistrationsController
def new
#user = User.new
#user.projects.build
end
def create
#user = User.new(getting_started_params)
redirect_to root, notice: "Done"
end
private
def getting_started_params
params.require(:user).permit(:first_name, :last_name, :phone, :password, :email, projects_attributes: [:user_id, :project_type_id, :name, :industry_id, :description, :budget_id, :project_status_id, feature_ids:[], addon_ids:[]])
end
end
But when I try and actually submit the form, it loads the getaction from the new controller, and the post action from the devise registration controller.
Started GET "/getting_started" for ::1 at 2016-10-17 09:15:58 +0200
Processing by GettingStartedController#new as HTML
Rendering getting_started/new.html.erb within layouts/application
Project_type Load (0.5ms) SELECT "project_types".* FROM "project_types"
Industry Load (1.1ms) SELECT "industries".* FROM "industries" ORDER BY "industries"."name" ASC
Feature Load (0.5ms) SELECT "features".* FROM "features" ORDER BY "features"."name" ASC
Addon Load (0.4ms) SELECT "addons".* FROM "addons"
Budget Load (0.4ms) SELECT "budgets".* FROM "budgets"
Rendered getting_started/new.html.erb within layouts/application (32.9ms)
Rendered layouts/_header.html.erb (1.9ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 97ms (Views: 86.4ms | ActiveRecord: 2.9ms)
Started POST "/users" for ::1 at 2016-10-17 09:16:54 +0200
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hYrC/15zIF3DzPvhpFQH6LVS9H8XbhfHY1aRkgc2iX6Mdfvz33/O4p72XTpmY4X8E6B+dGfOmjZw7IoizvYwSA==", "user"=>{"first_name"=>"John", "last_name"=>"Smith", "phone"=>"0340239402309", "email"=>"test#example.com", "password"=>"[FILTERED]", "project"=>{"name"=>"This is a test", "description"=>"Tester Description", "feature_ids"=>[""], "addon_ids"=>[""]}}, "project"=>{"project_type_id"=>"4", "industry_id"=>"2", "budget_id"=>"1"}, "commit"=>"Create account"}
Unpermitted parameter: project
(0.1ms) BEGIN
SQL (1.5ms) INSERT INTO "users" ("email", "encrypted_password", "created_at", "updated_at", "first_name", "last_name", "phone") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["email", "test#example.com"], ["encrypted_password", "$2a$11$VEVjSrnc5Y5c8ofXvNmlMOHrS.v4tQuBoKMLdHaSOA2S6fiVIHfE."], ["created_at", 2016-10-17 07:16:55 UTC], ["updated_at", 2016-10-17 07:16:55 UTC], ["first_name", "John"], ["last_name", "Smith"], ["phone", "0340239402309"]]
(139.1ms) COMMIT
(0.1ms) BEGIN
SQL (0.4ms) UPDATE "users" SET "sign_in_count" = $1, "current_sign_in_at" = $2, "last_sign_in_at" = $3, "current_sign_in_ip" = $4, "last_sign_in_ip" = $5, "updated_at" = $6 WHERE "users"."id" = $7 [["sign_in_count", 1], ["current_sign_in_at", 2016-10-17 07:16:55 UTC], ["last_sign_in_at", 2016-10-17 07:16:55 UTC], ["current_sign_in_ip", "::1/128"], ["last_sign_in_ip", "::1/128"], ["updated_at", 2016-10-17 07:16:55 UTC], ["id", 17]]
(0.3ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 319ms (ActiveRecord: 141.7ms)
I realise that devise does a whole bunch of other stuff besides simply recording the user data, so it may be better to rather move these actions to the Devise User::RegistrationController, and then tweak the accepted params. But how do you override Devise so that it doesn't auto use the devise create method the second you click the submit button, and would instead use a getting_started_create action?
First off getting started is a pretty horrible name for a controller since it is not a noun. You can't say a getting started. So lets change it to QuickstartsController.
Lets setup the routes for this resource:
Rails.application.routes.draw do
# These are your "normal" devise routes
devise_for :users
# This is the mapping for the "quickstart" routes
devise_for :quickstarts,
class_name: 'User',
only: [],
controllers: { registrations: 'quickstarts' }
# These are the actual routes for quickstarts
devise_scope :quickstart do
get "/quickstarts/new", to: "quickstarts#new", as: :new_quickstart
post "/quickstarts", to: "quickstarts#create", as: :quickstarts
end
end
Whenever you are overriding a library controller it is important to take some time to study how the class you are superclassing actually works.
If you look at the Devise controllers almost all the actions have a line like:
yield resource if block_given?
Which lets you tap into the flow of the original implementation by calling super with a block:
class QuickstartsController < Devise::RegistrationsController
# GET /quickstarts/new
def new
# This block is passed to the super class implementation:
super do |resource|
resource.projects.build
end
end
# POST /quickstarts
def create
# You can pass a block here too if you want.
super
end
private
# This should redirect to the newly created project
def after_sign_up_path_for(resource)
polymorphic_path( resource.projects.last )
end
# This is the method Devise devise calls for the params.
def sign_up_params
# Don't write your params sanitiation on one line! Its not cool.
params.require(:user)
.permit(
:first_name, :last_name, :phone, :password, :email,
projects_attributes: [
:user_id, :project_type_id, :name,
:industry_id, :description, :budget_id,
:project_status_id,
feature_ids:[],
addon_ids:[]
]
)
end
end
But how do you override Devise so that it doesn't auto use the devise
create method the second you click the submit button, and would
instead use a getting_started_create action?
Point the form to the correct controller - by passing the url option to form_for.
app/views/quickstarts/new.html.erb:
<h2>Getting Started</h2>
<%= form_for( resource, as: :user, url: quickstarts_path ) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<fieldset>
<legend>Project</legend>
<% f.fields_for :projects do |pf| %>
<%# ... %>
<% end %>
</fieldset>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
My main problem is, that when uploading via carrierwave the file isn't truly uploaded.
My console output:
#<OptionPic id: 4, image_url: "game_of_thrones___tyrion_lannister_by_stanbos-d79k...", created_at: "2015-08-07 06:08:01", updated_at: "2015-08-07 06:08:01", option_id: 12>]>
The call to the image is following
-#product.options.each do |option|
-option.option_pics.each do |op|
=image_tag op.image_url.to_s
If I inspect the element on my webpage, this is what I get:
<img src="/images/game_of_thrones___tyrion_lannister_by_stanbos-d79k0u9_modified.jpg" alt="Game of thrones tyrion lannister by stanbos d79k0u9 modified">
However settings on the uploader are as following:
class ProductImageUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
Needless to say I have neither an image in the assets/images folder nor a public/uploads folder created.
This works perfectly on my other project (public/uploads folder is created with the same syntax as above), where images are stored as a separate model. In my current project I want them as a sub-option for a product class.
The structure is following:
models - product, option, optionpic(ture)
A product can have many options and in turn an option can have many pictures. For example - product is a T-Shirt. Options are: material and color. For each color I want a different picture of the shirt.
This is why I have everything in my ProductsController:
Class ProductsController < ApplicationController
before_action :find_product, only: [:show]
def show
end
def index
#products = Product.all
end
def new
#product = Product.new
#option = #product.options.new
#option_pic = OptionPic.new
end
def edit
end
def create
#product = Product.create(product_params)
#option = #product.options.create(option_params)
#option.product_id = #product.id
#option.save
#option_pic = #option.option_pics.create(pic_params)
#option_pic.option_id = #option.id
flash[:success] = "Product successfully created!"
redirect_to products_path
end
private
def product_params
params.require(:product).permit(:title, :description, :advertising_text, :fancy_quote)
end
def option_params
params.require(:option).permit(:size, :weight, :price, :material, :product_id)
end
def pic_params
params.require(:option_pic).permit(:image_url, :option_id)
end
def find_product
#product = Product.find(params[:id])
end
end
My optionpic(ture) model:
class OptionPic < ActiveRecord::Base
mount_uploader :product_image, ProductImageUploader
belongs_to :option
end
I think I am making just some dumb newbie mistake, but after hours of search I just can't figure out what is wrong.
Edit
I figured out two things - I used image_url instead of picture_image and forgot to actually save the option_picture values in the controller, i.e. #option_pic.save
How ever now there is no data transmission when uploading:
SQL (0.3ms) INSERT INTO "option_pics" ("product_image", "option_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["product_image", nil], ["option_id", 18], ["created_at", "2015-08-07 08:03:28.559319"], ["updated_at", "2015-08-07 08:03:28.559319"]]
I updated every value from :image_url to :product_image (in the view, in the pic_params etc.)
Edit 2
As requested, my upload form:
%h1 Create new product
=form_for #product, url: products_path do |f|
%p
=f.label :title
=f.text_field :title
%br
=f.label :description
=f.text_area :description
%br
=f.label :advertising_text
=f.text_area :advertising_text
%br
=f.label :fancy_quote
=f.text_area :fancy_quote
%p
= fields_for #option do |o|
=o.label :price
=o.text_field :price
%br
=o.label :size
=o.text_field :size
%br
=o.label :weight
=o.text_field :weight
%br
=o.label :material
=o.text_field :material
%p
= fields_for #option_pic, html: { multipart: true } do |op|
= op.label 'Upload image'
= op.file_field :product_image
=f.submit
Edit 3
As requested, my log parameters
Started POST "/products" for ::1 at 2015-08-07 12:25:31 +0300
Processing by ProductsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"DOeZMvYpdoVmZRpsGmg2Gr9LIc9RYaS1KT1vdfhXI2BJaV3pPZZbZN8PJnvwQAig8wLPpIUORuf7Kjcw3BE6Zg==", "product"=>{"title"=>"fafa", "description"=>"", "advertising_text"=>"", "fancy_quote"=>""}, "option"=>{"price"=>"", "size"=>"", "weight"=>"", "material"=>""}, "option_pic"=>{"product_image"=>"level-3-on-rails-for-zombies-2-0eaaf0109f83459c5aedef30bdf8bd96.png"}, "commit"=>"Create Product"}
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO "products" ("title", "description", "advertising_text", "fancy_quote", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["title", "fafa"], ["description", ""], ["advertising_text", ""], ["fancy_quote", ""], ["created_at", "2015-08-07 09:25:31.365739"], ["updated_at", "2015-08-07 09:25:31.365739"]]
(0.3ms) COMMIT
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO "options" ("size", "material", "product_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["size", ""], ["material", ""], ["product_id", 29], ["created_at", "2015-08-07 09:25:31.369112"], ["updated_at", "2015-08-07 09:25:31.369112"]]
(0.3ms) COMMIT
(0.1ms) BEGIN
(0.1ms) COMMIT
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO "option_pics" ("product_image", "option_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["product_image", nil], ["option_id", 21], ["created_at", "2015-08-07 09:25:31.372492"], ["updated_at", "2015-08-07 09:25:31.372492"]]
(0.3ms) COMMIT
Redirected to http://localhost:3000/products
Completed 302 Found in 10ms (ActiveRecord: 2.1ms)
You are not accessing your params value properly. The following will fix that:
def pic_params
params.require(:option_pic).require(:product_image)
end
Also, you have to make your OptionPic belonging to your Option when you build it:
def new
#product = Product.new
#option = #product.options.new
#option_pic = #option.option_pics.new
end
If someone encounters same problem, I will post my solution - I decided to recreate this system using nested attributes, now everything work fine!
So here I have my 3 models:
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :subcategory
has_many :options
has_and_belongs_to_many :product_sizes
accepts_nested_attributes_for :options
end
The option class, which is the child of a product
class Option < ActiveRecord::Base
belongs_to :product
has_many :option_pics
accepts_nested_attributes_for :option_pics
end
And finally the option_pic, a child of an option
class OptionPic < ActiveRecord::Base
mount_uploader :product_image, ProductImageUploader
belongs_to :option
end
In the products controller my new and create actions look as following:
def new
#product = Product.new
option = #product.options.build
option_pic = option.option_pics.build
end
def edit
end
def create
#product = Product.new(product_params)
if #product.save!
flash[:success] = "Product successfully created!"
redirect_to products_path
end
end
private
def product_params
params.require(:product).permit(
:title, :description, :advertising_text, :fancy_quote, :category_id,
options_attributes: [:size, :weight, :price, :material, :product_id,
option_pics_attributes: [:product_image, :option_id]])
end
def find_product
#product = Product.find(params[:id])
end
The string params are double nested, which is important. Also important is the structure for the form_for helper. I did not refactor it, so right now it is one big list. The structure there is very important, I had my fields for option_pic intended on the level of the "f" variable, which was crucial and no images were uploaded.
=form_for #product, url: products_path do |f|
%p
=f.label :title
=f.text_field :title
%br
=f.label :description
=f.text_area :description
%br
=f.label :advertising_text
=f.text_area :advertising_text
%br
=f.label :fancy_quote
=f.text_area :fancy_quote
%br
=f.label :category_id
=f.collection_select :category_id, Category.all, :id, :title, { prompt: 'Please select category' }
%br
=f.label 'Product Size'
=f.collection_check_boxes(:product_size_ids, ProductSize.all, :id, :size)
%p
= f.fields_for :options do |builder|
=builder.label :price
=builder.text_field :price
%br
=builder.label :size
=builder.text_field :size
%br
=builder.label :weight
=builder.text_field :weight
%br
=builder.label :material
=builder.text_field :material
%br
=builder.fields_for :option_pics do |op|
= op.label 'Upload image'
= op.file_field :product_image
=f.submit
And voila, a wonderful commit:
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO "products" ("title", "description", "advertising_text", "fancy_quote", "category_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["title", "builder"], ["description", ""], ["advertising_text", ""], ["fancy_quote", ""], ["category_id", 1], ["created_at", "2015-08-11 11:34:11.618298"], ["updated_at", "2015-08-11 11:34:11.618298"]]
SQL (0.2ms) INSERT INTO "options" ("size", "price", "material", "product_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["size", ""], ["price", 555], ["material", ""], ["product_id", 82], ["created_at", "2015-08-11 11:34:11.619678"], ["updated_at", "2015-08-11 11:34:11.619678"]]
SQL (0.5ms) INSERT INTO "option_pics" ("product_image", "option_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["product_image", "b3c839_bd43d840e031469495137fa74e31faf4.jpg_srz_428_428_75_22_0.5_1.2_75_jpg_srz"], ["option_id", 66], ["created_at", "2015-08-11 11:34:11.620837"], ["updated_at", "2015-08-11 11:34:11.620837"]]
(0.3ms) COMMIT
I am using a custom controller to handle Devise actions.
class RegistrationsController < Devise::RegistrationsController
def new
#joining_group = params[:access_token]
session[:access_token] = params[:access_token]
super
end
def create
super
sign_in resource_name, resource # sign in the user so that the code below works
if params[:organization] # User is an admin and creates group
current_user.admin = true
new_group = Group.create( name: params[:organization], access_token: SecureRandom.hex ) # add super secret token to group so other users can be invited to join
current_user.group = new_group
current_user.save!
else # user is joining vis a vis email invitation with access_token
current_user.group_id = Group.where( access_token: session[:access_token] ).first.id
current_user.save!
end
end
def update
super
end
def group_params
params.require(:group).permit(:name)
end
end
However, when I try to create a new user I get the following error in my browser when I have an empty input tag (if all inputs are filled the create works just fine):
NoMethodError in RegistrationsController#create
undefined method `admin=' for nil:NilClass
Extracted source (around line #12):
10 super
11 if params[:organization] # User is an admin and creates group
12 current_user.admin = true
13 new_group = Group.create( name: params[:organization], access_token: SecureRandom.hex )
14 current_user.group = new_group
15 current_user.save!
The validatable module is turned on in my user class. My registration/new.html.erb view is as such:
<div class="logo">
<h1>VitalTracker</h1>
</div>
<div class="registration_box">
<% if #joining_group %>
<h2>Join Group</h2>
<% else %>
<h2>Create Account</h2>
<% end %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div>
<%= f.email_field :email, :autofocus => true, placeholder: "Email", class: "registration_input" %>
</div>
<div>
<%= f.password_field :password, placeholder: "Password", class: "registration_input" %>
</div>
<div>
<%= f.password_field :password_confirmation, placeholder: "Confirm Password", class: "registration_input" %>
</div>
<div>
<%= f.text_field :name, placeholder: "Name", class: "registration_input" %>
</div>
<% unless #joining_group %>
<div>
<%= text_field_tag "organization", nil, placeholder: "Organization", class: "registration_input" %>
</div>
<% end %>
<div>
<%= f.submit "Create Account", class: "registration_btn large_btn" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
Server log below:
Started POST "/users" for 127.0.0.1 at 2014-02-22 16:05:56 -0500
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"eBTmAyknoi92qdbhiirlUfjjtbdOiD8jzYwp6ZE9dwI=", "user"=>{"email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "name"=>""}, "organization"=>"", "commit"=>"Create Account"}
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Rendered devise/shared/_links.erb (0.3ms)
Rendered registrations/new.html.erb within layouts/application (3.8ms)
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "users" ("created_at", "current_sign_in_at", "current_sign_in_ip", "last_sign_in_at", "last_sign_in_ip", "name", "sign_in_count", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["created_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["current_sign_in_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["current_sign_in_ip", "127.0.0.1"], ["last_sign_in_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["last_sign_in_ip", "127.0.0.1"], ["name", ""], ["sign_in_count", 1], ["updated_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00]]
(0.6ms) COMMIT
(0.2ms) BEGIN
SQL (0.6ms) INSERT INTO "groups" ("access_token", "created_at", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["access_token", "103ff607863b1f766d3cd1b23d1f57dd"], ["created_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00], ["name", ""], ["updated_at", Sat, 22 Feb 2014 21:05:56 UTC +00:00]]
(0.4ms) COMMIT
(0.2ms) BEGIN
(0.2ms) ROLLBACK
Completed 422 Unprocessable Entity in 94ms
ActiveRecord::RecordInvalid (Validation failed: Email can't be blank):
app/controllers/registrations_controller.rb:17:in `create'
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.8ms)
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.1ms)
Rendered /Users/jonathantrope/.rvm/gems/ruby-2.0.0-p353#rails4/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (19.2ms)
Thanks.
If you want to use current_user, add before_filter :authenticate_user! to your controller. Looking at the source of Devise::RegistrationsController I think you want to use resource instead of current_user.
Btw creating an admin based on the params[:organization] is a bad idea.
current_user is nil because no-one is signed in.
You need something like this:
def create
super
# sign in after registration
sign_in resource_name, resource
# then the rest of your code shuold be ok
if params[:organization] # User is an admin and creates group
current_user.admin = true
# etc
The problem was due to calling current_user.save!, which prevented invalid create error messages to be shown by devise in the view as intended. Using current_user.save fixes it.
I'm stuck on something that doesn't make sense! I'm simply trying to submit a form with "comments" on a blog post.
Here is my form view:
<%= form_for #comment, :remote => true, :url => forumpost_comments_path(forumpost) do |s| %>
<div class="field">
<%= s.label :content, "Write a comment" %>
<%= s.text_area :content, :rows => "3" %>
</div>
<%= s.submit "Reply"%>
<% end %>
Here is my controller:
def create
#forumpost = Forumpost.find_by_id(params[:forumpost_id])
#comment = #forumpost.comments.build(params[:comment])
#comment.user_id = current_user.id
if #comment.save
redirect_to search_static_pages_path
else
redirect_to search_static_pages_path
end
end
Here is my model:
class Comment < ActiveRecord::Base
attr_accessible :content
belongs_to :user
belongs_to :forumpost
validates :user_id, presence: true
validates :forumpost_id, presence: true
end
And here are my logs:
Started POST "/forumposts/331/comments" for 127.0.0.1 at 2013-12-14 11:41:24 -0800
Processing by CommentsController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"3w3WACRYA6JEwvIg9C66k+cR1ZdRSWwA5Z+W0et1sS8=",
"forumpost"=>{"content"=>"test"}, "commit"=>"Reply", "forumpost_id"=>"331"}
(0.1ms) begin transaction
SQL (0.8ms) INSERT INTO "comments" ("content", "created_at", "forumpost_id", "updated_at", "user_id")
VALUES (?, ?, ?, ?, ?) [["content", nil], ["created_at", Sat, 14 Dec 2013 18:58:58 UTC +00:00],
["forumpost_id", 331], ["updated_at", Sat, 14 Dec 2013 18:58:58 UTC +00:00], ["user_id", 1]]
(14.3ms) commit transaction
As you can see, the content portion is nil even though I have filled out the content field and submitted it.
I would really appreciate any guidance on the matter! Thanks!
Rails nooby so I don't know what info to provide. Basically when my show action gets called from the pictures controller a new comment record is inserted. My output looks like this:
Started GET "/pictures/2" for 127.0.0.1 at Wed Oct 19 18:43:24 -0400 2011
Processing by PicturesController#show as HTML
Parameters: {"id"=>"2"}
Picture Load (0.2ms) SELECT "pictures".* FROM "pictures" WHERE "pictures"."id" = $1 LIMIT 1 [["id", "2"]]
Comment Load (0.4ms) SELECT "comments".* FROM "comments" WHERE "comments"."picture_id" = 2
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "comments" ("comment", "created_at", "downvote", "picture_id", "updated_at", "upvote") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["comment", nil], ["created_at", Wed, 19 Oct 2011 22:43:24 UTC +00:00], ["downvote", nil], ["picture_id", 2], ["updated_at", Wed, 19 Oct 2011 22:43:24 UTC +00:00], ["upvote", nil]]
(1.1ms) COMMIT
Rendered pictures/show.html.erb within layouts/application (32.2ms)
Completed 200 OK in 51ms (Views: 41.0ms | ActiveRecord: 7.5ms)
Show Controller:
def show
#picture = Picture.find(params[:id])
#comments = #picture.comments
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #picture }
end
end
Show View:
<p id="notice"><%= notice %></p>
<h2><%= #picture.title %></h2> <br />
<ul class="media-grid">
<li>
<a href="#">
<%= image_tag #picture.url %>
</a>
</li>
</ul>
<table>
<% #comments.each do |comment| %>
<tr>
<td><%= comment.comment %></td>
<td><%= comment.upvote %></td>
<td><%= comment.downvote %></td>
</tr>
<% end %>
</table>
<%= form_for [#picture, #picture.comments.create] do |f| %>
<%= f.label "Comment:" %><br />
<%= f.text_field :comment %>
<%= f.submit %>
<% end %>
<%= link_to 'Back', pictures_path %>
Models:
class Comment < ActiveRecord::Base
belongs_to :picture
end
class Picture < ActiveRecord::Base
has_many :comments
end
As far as I know, you dont want to use
<%= form_for [#picture, #picture.comments.create] do |f| %>
but
<%= form_for [#picture, #picture.comments.new] do |f| %>