I've been working with the acts_as_commentable_with_threading gem and I can't get the comments to save.
My controller:
class CommentsController < ApplicationController
def create
#comment_hash = params[:comment]
#obj = #comment_hash[:commentable_type].constantize.find(#comment_hash[:commentable_id])
# Not implemented: check to see whether the user has permission to create a comment on this object
#comment = Comment.build_from(#obj, current_user, #comment_hash[:body])
if #comment.save
flash[:notice] = "New comment saved!!!!!"
redirect_to status_path(#obj)
#redirect_to profiles_path(current_user)
else
flash[:alert] = "didn't save"
redirect_to status_path(#obj)
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment,:commentable_id,:commentable_type, :user_id, :body)
end
end
When I check the development log I can see that the values in the hash are all populated and I can see the transaction start the save, but it is immediately rolled back.
Started POST "/comments" for 127.0.0.1 at 2014-01-30 10:47:54 +0100
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ojRIz0hj0m8BL613Q9W4DHkYNZqO8eeMvR2gEM6Qhp8=", "comment"=> {"body"=>"test comment", "commentable_id"=>"52", "commentable_type"=>"Status"}, "commit"=>"Submit"}
[1m[35mStatus Load (0.1ms)[0m SELECT "statuses".* FROM "statuses" WHERE "statuses"."id" = ? ORDER BY created_at DESC LIMIT 1 [["id", "52"]]
[1m[36mUser Load (0.3ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1[0m
[1m[35m (0.1ms)[0m begin transaction
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
Redirected to http://localhost:3000/statuses/52
Completed 302 Found in 5ms (ActiveRecord: 0.6ms)
Related
Here is the code I'm trying to use in my controller:
profiles_controller.rb:
class ProfilesController < ApplicationController
...
def update
respond_to do |format|
# assume valid data sent (I've already tested for this)
if #user.update(user_params)
# password_reset? check's parameter passed to action that a check box was
# checked (which enables/disables password/confirmation fields. If unchecked,
# fields are disabled and no password parameters are sent to this action.
# #user was set to current_user in a before_action already
# inspecting #user at this point returns the same thing as current_user here
sign_in(:user, #user) if password_reset?
# current_user is still set to #user and is valid
# after redirection current_user becomes nil
format.html {
redirect_to home_path, notice: 'Your profile was successfully updated.'
}
else
format.html { render :edit }
end
end
end
...
private
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
#user_params ||= params.require(:user).permit(:first_name, :last_name, :email, :phone, :password, :password_confirmation, :reset_password)
end
def password_reset?
#user_params["reset_password"] == "1"
end
end
application_controller.rb:
class ApplicationController < ActionController::Base
...
private
...
def require_user
logger.debug "IN REQUIRE_USER, CURRENT_USER IS: #{current_user.inspect}"
unless current_user
store_location
redirect_to new_user_session_url, notice: "That url doesn't exist."
return false
end
end
def require_admin
# this line will actually log a user in
#sign_in(:user, User.first) unless current_user
logger.debug "IN REQUIRE_ADMIN, CURRENT_USER IS: #{current_user.inspect}"
unless current_user && current_user.is_admin?
redirect_to(home_path, notice: "That url doesn't exist.") and return false
end
end
...
end
development.log:
Started PATCH "/profile" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by ProfilesController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"....", "user"=>{....}, "commit"=>"Update Profile"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:47
IN REQUIRE_USER, CURRENT_USER IS: #<User id: 1 ....>
(0.1ms) begin transaction
↳ app/controllers/profiles_controller.rb:16
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND "users"."id" != ? LIMIT ? [["email", "...."], ["id", 1], ["LIMIT", 1]]
↳ app/controllers/profiles_controller.rb:16
User Update (0.3ms) UPDATE "users" SET "encrypted_password" = ?, "updated_at" = ? WHERE "users"."id" = ? [["encrypted_password", "$2a$11...."], ["updated_at", "2019-05-28 17:38:45.346414"], ["id", 1]]
↳ app/controllers/profiles_controller.rb:16
(2.3ms) commit transaction
↳ app/controllers/profiles_controller.rb:16
PASSWORDS PASSED IN SO USER PASSWORD CHANGE OCCURRED
REDIRECTING TO HOME PATH
Redirected to http://localhost:3000/admin
Completed 302 Found in 121ms (ActiveRecord: 3.2ms)
Started GET "/admin" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by Admin::PagesController#index as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:65
IN REQUIRE_ADMIN, CURRENT_USER IS: nil
Redirected to http://localhost:3000/
Filter chain halted as :require_admin rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.2ms)
Started GET "/" for 127.0.0.1 at 2019-05-28 10:38:45 -0700
Processing by PagesController#index as HTML
Rendering pages/index.html.erb within layouts/application
Rendered pages/index.html.erb within layouts/application (0.7ms)
Rendered application/_navigation.html.erb (1.7ms)
Rendered application/_alert.html.erb (0.3ms)
Completed 200 OK in 1152ms (Views: 1151.2ms | ActiveRecord: 0.0ms)
I've searched around and seen by_pass: true being passed to sign_in but that doesn't help. I've also tried #current_user = #user once I've signed the user in (#current_user is the direct instance variable for the Devise controller btw) and that does not help either.
Any ideas?
Devise ignores signin if the user is already signed in, try:
if #user.saved_change_to_encrypted_password? # for rails 5+, for previous - .encrypted_password_changed?
sign_in #user, force: true
end
You can signin new session if the user is already signed in.
Devise said
# Sign in a user bypassing the warden callbacks and stores the user
# straight in session. This option is useful in cases the user is
# signed in, but we want to refresh the credentials in session.
Please use like below one.
bypass_sign_in(#user)
When a user creates a password update action is hit.
module Users
class PasswordController < ApplicationController
skip_before_action :authenticate_user!
before_action :set_user
def setup
render file: "#{Rails.root}/public/404" unless #user&.sign_in_count&.zero?
end
def update
if #user.update_attributes(password_params)
sign_in(:user, #user)
redirect_to root_path, notice: 'Setup complete'
else
flash[:alert] = errors(#user)
render :setup
end
end
private
def password_params
params.require(:user).permit(:password, :password_confirmation)
end
def set_user
#user = User.find_by(confirmation_token: params[:token])
end
end
end
When the update action is hit.
This is what the console shows
Started PATCH "/users/password/wynEjv-E7uFp44EcwjbS" for ::1 at 2017-02-07 12:33:01 +1000
Processing by Users::PasswordController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"vIyPtidsM1GDNLh3n7gDDB2HzvR0QEEwAAvfMybNRn0/t4em4StiUVDyKwLC9i1OThoYguEae4T+xqLttjt1Pw==", "email"=>"test04#example.com", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Continue", "token"=>"wynEjv-E7uFp44EcwjbS"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = $1 LIMIT $2 [["confirmation_token", "wynEjv-E7uFp44EcwjbS"], ["LIMIT", 1]]
(0.1ms) BEGIN
SQL (0.5ms) UPDATE "users" SET "encrypted_password" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["encrypted_password", "$2a$11$o5wmmxnCv.rlPha52GR0IOG4tbhEJYNNF9tctcSLDMS/dvLAU0hXq"], ["updated_at", 2017-02-07 02:33:01 UTC], ["id", 9]]
(1.0ms) COMMIT
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 9], ["LIMIT", 1]]
(0.1ms) BEGIN
(0.2ms) COMMIT
Completed 401 Unauthorized in 129ms (ActiveRecord: 2.5ms)
Does anyone know why the sign_in method isn't working here?
I used it on few apps and it worked then.
Thank you for any help in advance.
You can use it like this
#user.update_with_password(password_params)
sign_in #user, :bypass => true
Hope it will work for you as it worked for me!
Im having a weird issue trying to force my users to change their passwords on first login.
My server output is telling me it completed the patch successfully, however when I go to log back into the app its still the old password? I'll post output below.
But first here is my code to make this happen:
#application_controller.rb
# Force PW Change On 1st Login
def after_sign_in_path_for(resource)
if current_user.sign_in_count == 1
edit_passwords_path
else
authenticated_root_path
end
end
#passwords_controller.rb
def edit
#user = current_user
end
def update
if current_user.update_without_password(user_params)
flash[:notice] = "Password updated successfully."
redirect_to authenticated_root_path
else
flash[:alert] = "There was a problem, please try again."
render :edit
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
#passwords form_for
<%= form_for current_user, url: passwords_path do |f| %>
password:<br />
<%= f.password_field :password %><br />
password_confirmation:<br />
<%= f.password_field :password_confirmation %><br />
<br />
<%= f.submit %>
<% end %>
#routes.rb
resource :passwords
The force password is doing everything it is supposed to except actually saving the new passwords.
my server output:
Started PATCH "/passwords" for ::1 at 2016-09-07 02:23:43 -0600
Processing by PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zUOrOdquBht6uwvjvBkPj2yaO0dCgL+3XGhKo0YV1+W/4rEEiiIRHwwOzRCqvSVeVkAO0M7c73ogcmgNQDq/DQ==", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update User"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.1ms) BEGIN
(0.1ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 0.7ms)
Started GET "/" for ::1 at 2016-09-07 02:23:43 -0600
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Processing by WelcomeController#index as HTML
Rendering welcome/index.html.erb within layouts/application
Rendered welcome/index.html.erb within layouts/application (0.4ms)
Rendered layouts/navigation/_unassigned.html.erb (0.5ms)
Rendered layouts/messages/_flash_msg.html.erb (0.5ms)
Completed 200 OK in 56ms (Views: 54.9ms | ActiveRecord: 0.0ms)
In PasswordsController#Update change update_without_password to update_with_password:
def update
if current_user.update_with_password(user_params)
flash[:notice] = "Password updated successfully."
redirect_to authenticated_root_path
else
flash[:alert] = "There was a problem, please try again."
render :edit
end
end
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've got three models set up. Users, guides, and comments. Users have many guides and comments. Guides belong to users and have many comments. Comments belong to users and guides.
When I run Comment.last.user in the console, it returns the information pertaining to the user. However, when I run Comment.last.guide in the console, it returns nil. Something is going wrong with the creation of the comment.
The models all have the classic has_many and belongs_to relationships set up, so I'll omit those from here. Here is the comments controller:
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /comments
# GET /comments.json
def index
#comments = Comment.all
end
# GET /comments/1
# GET /comments/1.json
def show
end
# GET /comments/new
def new
#comment = Comment.new
end
# GET /comments/1/edit
def edit
end
# POST /comments
# POST /comments.json
def create
#comment = current_user.comments.build(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to :back, notice: 'Comment was successfully created.' }
format.json { render action: 'show', status: :created, location: #comment }
else
format.html { render action: 'new' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /comments/1
# PATCH/PUT /comments/1.json
def update
respond_to do |format|
if #comment.update(comment_params)
format.html { redirect_to #comment, notice: 'Comment was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /comments/1
# DELETE /comments/1.json
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to comments_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
#comment = Comment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment).permit(:body, :user_id, :guide_id)
end
end
Here is the comments migration:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.references :user, index: true
t.references :guide, index: true
t.timestamps
end
end
end
Log output when creating comment:
Started POST "/comments" for 127.0.0.1 at 2014-01-08 08:30:54 -0500
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"D2BvBIgU+tniZvr2NgQE/TpHY6J2xHOUm701jqTcJ9A=", "comment"=>{"body"=>"NitinJ Sample Comment", "user_id"=>"some value", "guide_id"=>"some value"}, "commit"=>"Create Comment"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (21.7ms) INSERT INTO "comments" ("body", "created_at", "guide_id", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?) [["body", "NitinJ Sample Comment"], ["created_at", Wed, 08 Jan 2014 13:30:54 UTC +00:00], ["guide_id", 0], ["updated_at", Wed, 08 Jan 2014 13:30:54 UTC +00:00], ["user_id", 1]]
(21.0ms) commit transaction
Redirected to http://localhost:3000/guides/1-attack
Completed 302 Found in 53ms (ActiveRecord: 43.1ms)
Started GET "/guides/1-attack" for 127.0.0.1 at 2014-01-08 08:30:54 -0500
Processing by GuidesController#show as HTML
Parameters: {"id"=>"1-attack"}
Guide Load (0.2ms) SELECT "guides".* FROM "guides" WHERE "guides"."id" = ? LIMIT 1 [["id", "1-attack"]]
CACHE (0.0ms) SELECT "guides".* FROM "guides" WHERE "guides"."id" = ? LIMIT 1 [["id", "1-attack"]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Comment Load (0.2ms) SELECT "comments".* FROM "comments" WHERE "comments"."guide_id" = ? [["guide_id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Rendered comments/_form.html.erb (6.6ms)
Rendered guides/show.html.erb within layouts/application (18.9ms)
DEPRECATION WARNING: Calling #sum with a block is deprecated and will be removed in Rails 4.1. If you want to perform sum calculation over the array of elements, use `to_a.sum(&block)`. (called from _app_views_layouts__navbar_html_erb__2351226726967046587_2202447400 at /Users/DylanRichards/Desktop/runescapeguides/app/views/layouts/_navbar.html.erb:35)
Guide Load (0.2ms) SELECT "guides".* FROM "guides" WHERE "guides"."user_id" = ? [["user_id", 1]]
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = 't' AND "votes"."vote_scope" IS NULL [["votable_id", 1], ["votable_type", "Guide"]]
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = 'f' AND "votes"."vote_scope" IS NULL [["votable_id", 1], ["votable_type", "Guide"]]
Rendered layouts/_navbar.html.erb (7.4ms)
Completed 200 OK in 54ms (Views: 47.8ms | ActiveRecord: 1.5ms)
Second log output
Started POST "/guides/1-attack/comments" for 127.0.0.1 at 2014-01-08 08:52:29 -0500
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"D2BvBIgU+tniZvr2NgQE/TpHY6J2xHOUm701jqTcJ9A=", "comment"=>{"body"=>"Another sample NitinJ comment.", "user_id"=>"some value", "guide_id"=>"some value"}, "commit"=>"Create Comment", "guide_id"=>"1-attack"}
Completed 500 Internal Server Error in 69ms
NoMethodError (undefined method `[]=' for nil:NilClass):
app/controllers/comments_controller.rb:27:in `create'
Rendered /Users/DylanRichards/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.0ms)
Rendered /Users/DylanRichards/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.7ms)
Rendered /Users/DylanRichards/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.5ms)
Rendered /Users/DylanRichards/.rvm/gems/ruby-2.0.0-p247/gems/actionpack-4.0.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (21.7ms)
try this <%= f.association :guide, :as => :hidden, :input_html => { :value => #guide.id }%>
So I have two models Topic, Client. A Client has_and_belongs_to_many :topics, and a Topic has_and_belongs_to_many :clients.
Basically, what I want to happen is...when someone goes to my Topic#index, depending on how they got there (i.e. either via client/:id/topics or just /topics), I want the behavior of the create & new to be different. i.e. at /topics, it just creates a topic. At client/:id/topics it creates a topic and assigns it to that client.
My routes look like this:
resources :topics
resources :clients do
resources :topics
end
My Topics Controller looks like this:
def new
if params[:client_id]
#client = Client.find(params[:client_id])
#topic = #client.topics.build
else
#topic = Topic.new
end
respond_to do |format|
format.html # new.html.erb
format.json { render json: #topic }
end
end
def create
if params[:client_id]
#client = Client.find(params[:client_id])
#topic = #client.topics.build(params[:topic])
else
#topic = Topic.new(params[:topic])
end
respond_to do |format|
if #topic.save
format.html { redirect_to #topic, notice: 'Topic was successfully created.' }
format.json { render json: #topic, status: :created, location: #topic }
else
format.html { render action: "new" }
format.json { render json: #topic.errors, status: :unprocessable_entity }
end
end
end
My views/topics/_form.html.erb looks like this:
<%= form_for([#client, #topic]) do |f| %>
...
<% end %>
However, when I perform an action from client/:id/topics this is what the logs look like:
Started GET "/clients/1/topics/new" for 127.0.0.1 at 2012-09-10 14:33:06 -0500
Processing by TopicsController#new as HTML
Parameters: {"client_id"=>"1"}
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1 [["id", "1"]]
Rendered topics/_form.html.erb (3.6ms)
Rendered topics/new.html.erb within layouts/application (4.7ms)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
(0.2ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = 1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))
Rendered layouts/_navigation.html.erb (7.2ms)
Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 61ms (Views: 57.0ms | ActiveRecord: 0.7ms)
That looks good...everything seems to be in order here. But it is in the POST that things seem to be not working:
Started POST "/clients/1/topics" for 127.0.0.1 at 2012-09-10 14:33:13 -0500
Processing by TopicsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172LuZQPv8=", "topic"=>{"name"=>"AMZN"}, "commit"=>"Create Topic", "client_id"=>"1"}
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1 [["id", "1"]]
(0.1ms) begin transaction
SQL (186.2ms) INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Mon, 10 Sep 2012 19:33:13 UTC +00:00], ["name", "AMZN"], ["updated_at", Mon, 10 Sep 2012 19:33:13 UTC +00:00]]
(4.6ms) commit transaction
Redirected to http://localhost:3000/topics/4
Completed 302 Found in 198ms (ActiveRecord: 191.1ms)
You will notice there is no assignment of the new topic to the client.
What am I missing?
Thanks!
Edit 1
Added puts debug statements to my create action, and this is the result I got after the POST action was executed - which indicates that is getting the params[:client_id] and not just params[:id]:
Served asset /application.js - 304 Not Modified (1ms)
**************************************************
This is the params[:client_id] => {3}
**************************************************
This is the params[:id] => {}
Started POST "/clients/3/topics" for 127.0.0.1 at 2012-09-10 15:06:31 -0500
Processing by TopicsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172LuZQc5NYoiMSzDD3oY9vGmxxCX0OdxcGm4GSPv8=", "topic"=>{"name"=>"TEST2"}, "commit"=>"Create Topic", "client_id"=>"3"}
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1 [["id", "3"]]
(0.1ms) begin transaction
SQL (0.7ms) INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Mon, 10 Sep 2012 20:06:31 UTC +00:00], ["name", "TEST2"], ["updated_at", Mon, 10 Sep 2012 20:06:31 UTC +00:00]]
(3.3ms) commit transaction
Redirected to http://localhost:3000/topics/6
Completed 302 Found in 11ms (ActiveRecord: 4.3ms)
Edit 2:
So I tried something else that seems to work, but I would love to know why the above doesn't work.
If, in my Topic#create I just do this:
#client = Client.find(params[:client_id])
#topic = Topic.new(params[:topic])
#client.topics << #topic
It works fine.
But, again...I would love to know why the .build doesn't for HABTM or in this situation.
I think the issue is in the params[:client_id] it may be params[:id].
Can you put a puts statement in your if else block of create action, and then see which one is showing up when you hit the page(create a topic)
EDIT
You need to include accepts_nested_attributes_for in your model to support dynamic building of nested object attributes.
Refer this.
It seems I have to explicitly call save after the build is done on my #client object.
Otherwise, ActiveRecord won't save the transaction and insert a new record in the join_table.