I am uploading legacy articles to my Rails app. I am sending created_at as a parameter in my request as recommended in this answer. However, this attribute seemingly is not passed "through". I can puts(params[:created_at]) and see my custom created_at, yet in the logs the article is INSERTed with a created_at of the current timestamp.
Here is my articles controller:
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :update, :destroy]
...
# POST /articles
def create
#section = Section.friendly.find(params[:section_id])
# Can't let people publish by default
#article = #section.articles.build(
article_params.merge(is_published: false)
)
if #article.save
render json: #article, status: :created, location: #article
else
render json: #article.errors, status: :unprocessable_entity
end
end
end
My request is:
http POST :3000/articles title='example' section_id=1 content="<p>the section exists.</p>" slug="example" created_at="2017-06-109T17:57:55.149-05:00"
The logs:
Started POST "/articles" for 127.0.0.1 at 2017-11-24 12:05:06 -0500
Processing by ArticlesController#create as HTML
Parameters: {"title"=>"example", "section_id"=>"1", "content"=>"<p>the section exists.</p>", "slug"=>"example", "created_at"=>"2017-06-109T17:57:55.149-05:00", "article"=>{"title"=>"example", "slug"=>"example", "content"=>"<p>the section exists.</p>", "created_at"=>"2017-06-109T17:57:55.149-05:00", "section_id"=>"1"}}
Section Load (0.3ms) SELECT "sections".* FROM "sections" WHERE "sections"."slug" = $1 ORDER BY "sections"."id" ASC LIMIT $2 [["slug", "1"], ["LIMIT", 1]]
Section Load (0.4ms) SELECT "sections".* FROM "sections" WHERE "sections"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.2ms) BEGIN
SQL (0.6ms) INSERT INTO "articles" ("title", "slug", "content", "is_published", "created_at", "updated_at", "section_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["title", "example"], ["slug", "example"], ["content", "<p>the section exists.</p>"], ["is_published", "f"], ["created_at", "2017-11-24 12:05:06.175751"], ["updated_at", "2017-11-24 12:05:06.175751"], ["section_id", 1]]
(0.8ms) COMMIT
Completed 201 Created in 38ms (Views: 1.1ms | ActiveRecord: 8.0ms)
In my schema.rb:
create_table "articles", force: :cascade do |t|
...
t.datetime "created_at", null: false
My model has no extra methods/callbacks that would ruin the request. It only contains relationships. I don't know if this is relevant, but I saw it in a GitHub issue somewhere: articles and users are in a many2many with an authorships model, and I use devise to authenticate users.
In conclusion, the app is receiving the created_at param just fine, but it is overridden with the default timestamp. If I set record_timestamps to false, the created_at just becomes nil.
Why is my created_at just seemingly ignored?
Rails 5.1, Ruby 2.4.2, Postgres 10.1
Answer given by max: there was a syntatical error in my timestamp. It was not valid, and was ignored by Rails.
Related
I have the following relations set up:
user has_many quizzes
quiz belongs_to user
quiz has_many questions
question belongs_to quiz
App is set up to use PostgreSQL. I'm trying to bulk insert a bunch of records using the insert_all! method
begin
quiz = user.quizzes.create!(title: title, slug: slug)
quiz_questions = params[:quiz][:questions].map! do |q|
# creating an attribute hash here (code removed for conciseness of question)
end
result = quiz.questions.insert_all!(quiz_questions)
This threw an error which was caught by my "catch all" block
rescue ActiveRecord::ActiveRecordError
render json: { message: ['Something went wrong'] }, status: 500
The running server console printed this message:
TRANSACTION (0.9ms) BEGIN
↳ app/controllers/quizzes_controller.rb:14:in `create'
Quiz Create (2.8ms) INSERT INTO "quizzes" ("title", "user_id", "slug", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["title", "a quiz"], ["user_id", 1], ["slug", "a-quizk2DqYk"], ["created_at", "2021-12-01 05:00:05.800134"], ["updated_at", "2021-12-01 05:00:05.800134"]]
↳ app/controllers/quizzes_controller.rb:14:in `create'
TRANSACTION (1.6ms) COMMIT
↳ app/controllers/quizzes_controller.rb:14:in `create'
Question Bulk Insert (0.6ms) INSERT INTO "questions" ("question","a","b","c","d","score","answer","quiz_id") VALUES ('what is name', 'str', 'char', 'num', 'bool', 5, 'A', 1), ('die', 'yes', 'no', 'ok', 'what', 5, 'B', 1) RETURNING "id"
↳ (eval):6:in `block in insert_all!'
Completed 500 Internal Server Error in 153ms (Views: 0.2ms | ActiveRecord: 38.1ms | Allocations: 49609)
So I think I am not calling insert_all! correctly because the server just does an insert without the BEGIN and COMMIT bookends. Also, I would like to know which error is being thrown and caught by the catch all block. What would be the correct way to do insert_all! ?
you could wrap your bulk insert into a transaction
def bulk_insert
ActiveRecord::Base.transaction do
quiz = user.quizzes.create!(title: title, slug: slug)
quiz_questions = params[:quiz][:questions].map! do |q|
# creating an attribute hash here
# ...
# note that you could validate attribute manually
raise ActiveRecord::Rollback if q.description.blank?
end
result = quiz.questions.insert_all!(quiz_questions)
end
rescue ActiveRecord::Rollback => e
puts e
end
I have a Quote model in my rails app which has various attr types, some of which are being sent to / saved by the db, some are not and I cannot understand why. Please can you help me understand, thanks.
quotes_controller.rb
class QuotesController < ApplicationController
def create
#quote = Quote.new(quote_params)
if #quote.save
redirect_to root_url, notice: 'Quote request created'
else
render :new
end
end
private
def quote_params
params.require(:quote).permit(:gla, :prev_cover, :co_name, :postcode, :industry, :lives_overseas,
:scheme_start_date, :payment_frequency, :commision_level)
end
end
quote.rb model
class Quote < ApplicationRecord
validates :gla, presence: { message: "Must be selected" }
enum industry: [ :financial_services, :architect, :business_consultancy ]
enum payment_frequency: [ :annually, :monthly ]
end
schema.rb
create_table "quotes", force: :cascade do |t|
t.boolean "prev_cover"
t.string "co_name"
t.integer "co_number"
t.string "postcode"
t.string "industry"
t.boolean "lives_overseas"
t.date "scheme_start_date"
t.string "payment_frequency"
t.integer "commission_level"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "gla"
end
rails console:
Pry> Quote.last.attributes
Quote Load (0.4ms) SELECT "quotes".* FROM "quotes" ORDER BY "quotes"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> {"id"=>6,
"prev_cover"=>true,
"co_name"=>"test1",
"co_number"=>nil,
"postcode"=>"al1 1aa",
"industry"=>nil,
"lives_overseas"=>true,
"scheme_start_date"=>Wed, 31 May 2017,
"payment_frequency"=>nil,
"commission_level"=>nil,
"created_at"=>Wed, 31 May 2017 19:23:07 UTC +00:00,
"updated_at"=>Wed, 31 May 2017 19:23:07 UTC +00:00,
"gla"=>true}
Stack Trace:
Started POST "/quotes" for 127.0.0.1 at 2017-05-31 21:04:37 +0100
Processing by QuotesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ILAo0Bs9Wq9lrVPlM2e6+a1kioV9zbni9Uxd5Yt/QSLNY3aVWyJ4TsEUmXN62RWgbueHksr/yN6avwEm8v7bEQ==", "quote"=>{"gla"=>"1", "prev_cover"=>"true", "co_name"=>"testing1", "co_number"=>"123456", "postcode"=>"al1 1aa", "industry"=>"", "lives_overseas"=>"true", "scheme_start_date(1i)"=>"2017", "scheme_start_date(2i)"=>"5", "scheme_start_date(3i)"=>"31", "payment_frequency"=>"", "commission_level"=>"10"}, "commit"=>"Get quote"}
Unpermitted parameters: co_number, commission_level
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO "quotes" ("prev_cover", "co_name", "postcode", "lives_overseas", "scheme_start_date", "created_at", "updated_at", "gla") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["prev_cover", "t"], ["co_name", "testing1"], ["postcode", "al1 1aa"], ["lives_overseas", "t"], ["scheme_start_date", "2017-05-31"], ["created_at", "2017-05-31 20:04:37.489368"], ["updated_at", "2017-05-31 20:04:37.489368"], ["gla", "t"]]
(0.3ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 3ms (ActiveRecord: 0.6ms)
Started GET "/" for 127.0.0.1 at 2017-05-31 21:04:37 +0100
Processing by QuotesController#new as HTML
Rendering quotes/new.html.erb within layouts/application
Rendered quotes/new.html.erb within layouts/application (9.3ms)
Completed 200 OK in 34ms (Views: 32.7ms | ActiveRecord: 0.0ms)
From Rails console.
[1] pry(main)> Quote.last
Quote Load (0.2ms) SELECT "quotes".* FROM "quotes" ORDER BY "quotes"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Quote:0x007f951b14e918
id: 7,
prev_cover: true,
co_name: "testing1",
co_number: nil,
postcode: "al1 1aa",
industry: nil,
lives_overseas: true,
scheme_start_date: Wed, 31 May 2017,
payment_frequency: nil,
commission_level: nil,
created_at: Wed, 31 May 2017 20:04:37 UTC +00:00,
updated_at: Wed, 31 May 2017 20:04:37 UTC +00:00,
gla: true>
Ok stack trace and #toddmetheny help me sort out the missing or typo'd permitted attrs. Now just the enums Quote.industries and Quote.payment_frequencies whose values aren't getting saved.
Ok, so code changed to;
And this sends the attrs from the form, but they still don't get created in the db, stack trace:
Started POST "/quotes" for 127.0.0.1 at 2017-05-31 21:39:58 +0100
Processing by QuotesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"rkgX7CwrEHS/KnqG1C77mYkCiCEOWGshTxMCsbtGPdjGiDP20J4ccrAgplAGuKrdJyhECRWrsmXI0Ee9GNa6Zw==", "quote"=>{"gla"=>"1", "prev_cover"=>"true", "co_name"=>"halejulia", "co_number"=>"134532", "postcode"=>"al1 1aa", "industry"=>"financial_services", "lives_overseas"=>"true", "scheme_start_date(1i)"=>"2017", "scheme_start_date(2i)"=>"5", "scheme_start_date(3i)"=>"31", "payment_frequency"=>"monthly", "commission_level"=>"10"}, "commit"=>"Get quote"}
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO "quotes" ("prev_cover", "co_name", "co_number", "postcode", "industry", "lives_overseas", "scheme_start_date", "payment_frequency", "commission_level", "created_at", "updated_at", "gla") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id" [["prev_cover", "t"], ["co_name", "halejulia"], ["co_number", 134532], ["postcode", "al1 1aa"], ["industry", 0], ["lives_overseas", "t"], ["scheme_start_date", "2017-05-31"], ["payment_frequency", 1], ["commission_level", 10], ["created_at", "2017-05-31 20:39:58.957674"], ["updated_at", "2017-05-31 20:39:58.957674"], ["gla", "t"]]
(0.3ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 3ms (ActiveRecord: 0.7ms)
rails console :
Quote.last.payment_frequency
Quote Load (0.4ms) SELECT "quotes".* FROM "quotes" ORDER BY "quotes"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> nil
So still the params aren't being persisted in the db, they're permitted params! any ideas?
Strange, a psql select * from .. query shows that the values have been saved, yet Rails console; Quote.last.payment_frequency returns nil???
Aha, i see that for a enum the column type should be integer, yet it is string in my model, could this be the issue perhaps?
Data type of enum'd attrs changed to integer and all behaves as expected.
Post the stack trace. co_number isn't whitelisted in the permitted params. So that's at least part of the issue with that particular field. The others are...but post what you're actually seeing in the logs so we can see what's being passed through the form. There will also be messages in the stack trace that give you clues as to why those values aren't saving.
Update: the stack trace lists 2 unpermitted parameters: co_number and commission_level (you have a typo permitting commission level and co_number isn't there)
A couple things have blank values, too...like payment_frequency and industry...I'd dig into why those things are blank if they shouldn't be. Does the form have values for those things? They aren't being passed. That seems to account for the rest of your nil values.
Rails 4.2.6
routes:
scope module: 'v1', defaults: { format: :json } do
resources :blog_posts, except: [:new, :edit] do
resources :comments, only: :create
end
end
Comments controller:
class V1::CommentsController < ApplicationController
before_action :set_blog_post
def create
comment = #blog_post.comments.new(comments_params)
comment.user = current_user
comment.save
respond_with(comment)
end
end
Why respond_with method didn't respond with comment object?
Logs:
Started POST "/blog_posts/1/comments" for ::1 at 2016-04-17 23:26:43 +0600
ActiveRecord::SchemaMigration Load (0.6ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by V1::CommentsController#create as JSON
Parameters: {"comment"=>{"message"=>"foobar"}, "blog_post_id"=>"1"}
User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT 1 [["email", "test#test.com"]]
(0.1ms) begin transaction
SQL (0.4ms) UPDATE "users" SET "current_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = ? [["current_sign_in_at", "2016-04-17 17:26:44.221258"], ["sign_in_count", 2], ["updated_at", "2016-04-17 17:26:44.222139"], ["id", 1]]
(0.7ms) commit transaction
BlogPost Load (0.4ms) SELECT "blog_posts".* FROM "blog_posts" WHERE "blog_posts"."id" = ? LIMIT 1 [["id", 1]]
(0.1ms) begin transaction
SQL (1.5ms) INSERT INTO "comments" ("message", "blog_post_id", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["message", "foobar"], ["blog_post_id", 1], ["user_id", 1], ["created_at", "2016-04-17 17:26:44.259405"], ["updated_at", "2016-04-17 17:26:44.259405"]]
(0.7ms) commit transaction
Completed 500 Internal Server Error in 102ms (ActiveRecord: 5.5ms)
NoMethodError (undefined method `comment_url' for #<V1::CommentsController:0x007f85ec9a98d0>):
app/controllers/v1/comments_controller.rb:9:in `create'
I have the same respond_with with blog_post in V1::BlogPostController and I got a response without errors.
As a workaround I have used render json: comment
NoMethodError (undefined method `comment_url' for V1::CommentsController:0x007f85ec9a98d0
Your comments are nested inside blog_posts, so respond_with(comment) doesn't work. Instead you need to use
respond_with(#blog_post, comment)
or
respond_with comment, location: blog_post_comment_path(#blog_post, comment)
I have a problem with nested attributes. Creating works but when I update, the error message shows me that the values in the relation are not set. I can't find the reason.
The main model
class Product < ActiveRecord::Base
has_many :product_options
accepts_nested_attributes_for :product_options,
:allow_destroy => true,
:reject_if => proc { | r | r["name"].blank? or r["value"].blank? }
end
The nested model
class ProductOption < ActiveRecord::Base
belongs_to :product
validates :name, :presence => true
validates :value, :presence => true
end
The controller is a bit shorted.
Items is a model where Product is related to as has_one
class Admin::ProductsController < Admin::ApplicationController
before_action :set_product, only: [ :new, :show, :edit, :update, :destroy ]
def create
#product = Product.new( product_params )
respond_to do |format|
if #product.save
#product.product_options.build
format.js { render :js => "alert( 'Daten gespeichert!' );" }
else
format.js { render :js => 'alert( "Fehler beim Speichern!" );' }
end
end
end
def update
respond_to do |format|
if #product.update( product_params )
format.js { render :js => "alert( 'Daten gespeichert!' );" }
else
require "pp"
pp #product.errors
format.js { render :js => 'alert( "Fehler beim Speichern!" );' }
end
end
end
private
# UPDATE: creating the product_options at this time
# produces the described error :)
def set_product
#item = Item.find_by_id( params[ :item_id ] ) if params[ :item_id ]
#product = #item.product ? #item.product : #item.build_product
# WRONG Place for generating new options
# 2.times { #product.product_options.build }
end
def product_params
params.require( :product ).permit( :item_id, :name, :title, :active, :product_options_attributes => [ :id, :name, :value, :_destroy ] )
end
end
The console output for the create is working and looks like
Started POST "/admin/items/653/product" for 127.0.0.1 at 2014-02-14 15:12:14 +0100
Processing by Admin::ProductsController#create as JS
Parameters: {"utf8"=>"✓", "product"=>{"item_id"=>"653", "name"=>"1", "title"=>"1", "active"=>"1", "product_options_attributes"=>{"0"=>{"name"=>"aaa", "value"=>"aaaa"}}}, "commit"=>"Create Product", "item_id"=>"653"}
User Load (1.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1
(0.6ms) BEGIN
SQL (17.5ms) INSERT INTO "products" ("created_at", "item_id", "name", "title", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00], ["item_id", 653], ["name", "1"], ["title", "1"], ["updated_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00]]
SQL (1.3ms) INSERT INTO "product_options" ("created_at", "name", "product_id", "updated_at", "value") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["created_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00], ["name", "aaa"], ["product_id", 28], ["updated_at", Fri, 14 Feb 2014 14:12:14 UTC +00:00], ["value", "aaaa"]]
Item Load (1.0ms) SELECT "items".* FROM "items" WHERE "items"."id" = $1 ORDER BY "items"."id" ASC LIMIT 1 [["id", 653]]
ProductOption Load (1.3ms) SELECT "product_options".* FROM "product_options" WHERE "product_options"."product_id" = $1 [["product_id", 28]]
Rendered admin/products/_show.html.erb (7.6ms)
Rendered admin/products/create.js.erb (9.2ms)
Completed 200 OK in 448ms (Views: 40.0ms | ActiveRecord: 27.1ms)
The the update. I doesn't work and gives an error that the nested fields are empty. It's the pp inside the update method
Started PATCH "/admin/items/653/product" for 127.0.0.1 at 2014-02-14 15:15:03 +0100
Processing by Admin::ProductsController#update as JS
Parameters: {"utf8"=>"✓", "product"=>{"item_id"=>"653", "name"=>"1", "title"=>"1", "active"=>"1", "product_options_attributes"=>{"0"=>{"name"=>"aaa", "value"=>"aaaa", "id"=>"9"}, "1"=>{"name"=>"bbb", "value"=>"bbbb"}}}, "commit"=>"Update Product", "item_id"=>"653"}
User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1
Item Load (0.6ms) SELECT "items".* FROM "items" WHERE "items"."id" = 653 LIMIT 1
Product Load (0.9ms) SELECT "products".* FROM "products" WHERE "products"."item_id" = $1 ORDER BY "products"."id" ASC LIMIT 1 [["item_id", 653]]
(0.6ms) BEGIN
ProductOption Load (1.3ms) SELECT "product_options".* FROM "product_options" WHERE "product_options"."product_id" = $1 AND "product_options"."id" IN (9) [["product_id", 28]]
(0.5ms) ROLLBACK
#<ActiveModel::Errors:0x007f8bdeb9f818
#base=
#<Product id: 28, item_id: 653, content: nil, active: 1, created_at: "2014-02-14 14:12:14", updated_at: "2014-02-14 14:12:14", name: "1", title: "1", ordernumber: "">,
#messages=
{:"product_options.name"=>["can't be blank"],
:"product_options.value"=>["can't be blank"]}>
Completed 200 OK in 18ms (Views: 0.1ms | ActiveRecord: 5.1ms)
I think I know what is the problem with your code. The accepts_nested_attributes_for does not require you to build any of the associated models. If the appropriate params are passed in then the model automatically builds or updates the associations.
In your case in the update method what you do is the following:
You find the relevant product. So far so good (although you could actually use a specific product id in your form)
Then you build two product options (in #set_product). This is the problem.
And in the end you update the model based on the parameters.
Now the problem with the second step is that you basically build two empty associated instances. Those are not affected by the accepts_nested_attributes. As a result you are trying to save 2+2 product options (the ones you build and the ones created by the params). Obviously you get the validation error due to the fact the two of the models have no attributes set.
You can make sure my hypothesis is correct by removing the validators from ProductOption. On update you should get 4 associated product options persisted.
I have this in the Model:
after_create do |comment|
CommentMailer.comment_email(self).deliver
end
This in CommentMailer:
class CommentMailer < ActionMailer::Base
helper ActionView::Helpers::UrlHelper
include CommentHelper
helper :comment
def comment_email(user, comment, commentable)
mail(to: user.email,
subject: "You have left a comment",
from: "comments#lumeo.com",
bcc: "brian#lumeo.com")
end
end
And this in CommentHelper:
module CommentHelper
def find_commentable
#comment = Comment.find(params[:comment])
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
end
I'm getting this error:
Started POST "/requests/6/comments" for 127.0.0.1 at 2012-11-30 17:28:55 -0800
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"R62NH5/EE34FPapEqy7mfpa0wKz18GtSdhH8MGYq2Ec=", "comment"=>{"content"=>"post", "show"=>"true"}, "commit"=>"Create Comment", "request_id"=>"6"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 ORDER BY users.created_at DESC LIMIT 1
Request Load (0.3ms) SELECT "requests".* FROM "requests" WHERE "requests"."id" = $1 LIMIT 1 [["id", "6"]]
CACHE (0.0ms) SELECT "requests".* FROM "requests" WHERE "requests"."id" = $1 LIMIT 1 [["id", "6"]]
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO "comments" ("commentable_id", "commentable_type", "content", "created_at", "show", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["commentable_id", 6], ["commentable_type", "Request"], ["content", "post"], ["created_at", Sat, 01 Dec 2012 01:28:55 UTC +00:00], ["show", true], ["updated_at", Sat, 01 Dec 2012 01:28:55 UTC +00:00], ["user_id", 2]]
(0.2ms) ROLLBACK
Completed 500 Internal Server Error in 136ms
ArgumentError (wrong number of arguments (1 for 3)):
app/mailers/comment_mailer.rb:5:in `comment_email'
app/models/comment.rb:27:in `block in <class:Comment>'
app/controllers/comments_controller.rb:22:in `create'
Looks like simple typos.
Line 7, as noted in the exception:
commentable = #comment.commentable
So, the issues:
You're calling #comment.commentabe, but #comment is nil
Hence the error: undefined method 'commentable' for nil:NilClass
#comment is nil in your mailer method because you're passing it in as comment NOT #comment, yet you're trying to reference it as #comment.
Also, why are you passing in commentable as a parameter, but on line 7 you're setting commentable again - this is redundant? Just use the already available commentable variable that you're passing in as a param. In fact, you seem to be doing this with several variables, yet I can't tell (because you don't show the mailer template) whether or not you're actually using them.
It could be that you could use something simpler like:
So, this should (probably) work:
def comment_email(user, comment, commentable)
mail(to: user.email,
subject: "You have left a comment",
from: "comments#lumeo.com",
bcc: "brian#lumeo.com")
end
If you post your mail template (so I can see what the body of the email looks like) I can help you get the variables into the template.