uuid_it : Can't mass-assign protected attributes: uuid - ruby-on-rails

I used uuid_id gem to generate UUID for various models in my application(Rails 3.2.5 with Ruby 1.9.3p194). I correctly followed the steps given here
I am getting this error while creating the model tagged as uuid_it. It works fine if I remove uuid_it call from the model
Here is snapshot of the log
SQL (2.1ms) INSERT INTO "applications" ("created_at", "description", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Mon, 03 Sep 2012 10:17:59 UTC +00:00], ["description", "data mining"], ["name", "BlueBerry"], ["updated_at", Mon, 03 Sep 2012 10:17:59 UTC +00:00]]
Uuid Load (1.2ms) SELECT "uuids".* FROM "uuids" WHERE "uuids"."uuidable_id" = 5 AND "uuids"."uuidable_type" = 'Application' LIMIT 1
(0.2ms) ROLLBACK
Completed 500 Internal Server Error in 81ms
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: uuid):
app/controllers/applications_controller.rb:13:in `create'
where line 13 is application.create
EDIT
app/controllers/applications.rb
class ApplicationsController < ApplicationController
# some code here
def create
#application = Application.new(params[:application])
#application.creator = current_user
#application.organization = current_organization
if #application.save
redirect_to #application, notice: "Successfully created application."
else
render action: 'new'
end
end
# few lines here
end

Related

Ruby on Rails: How to POST in my API?

I'm trying to create a task, but the attributes are null
Mi controller:
#app/controllers/api/v1/tasks_controller.rb
def create
respond_with Task.create(params[:Task])
end
I tried do POST to localhost:3000/api/v1/tasks with this data:
{"task": {"name":"hello world"}} or {"name":"hello world"}
but the result has attributes null:
#Response Body
{
"id": 1,
"name": null,
"created_at": "2014-03-23T22:41:37.961Z",
"updated_at": "2014-03-23T22:41:37.961Z"
}
Update:
# Server log
Started POST "/api/v1/tasks" for 127.0.0.1 at 2014-03-23 17:03:03 -0600
Processing by Api::V1::TasksController#create as JSON
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "tasks" ("created_at", "updated_at") VALUES (?, ?) [["created_at", Sun, 23 Mar 2014 23:03:03 UTC +00:00], ["updated_at", Sun, 23 Mar 2014 23:03:03 UTC +00:00]]
(153.5ms) commit transaction
Completed 201 Created in 159ms (Views: 0.6ms | ActiveRecord: 154.0ms)
Thanks vee, emcanes, Carlos Figueiredo and BroiSatse for your answers. I solved the problem.
I changed create action:
#app/controllers/api/v1/tasks_controller.rb
def create
respond_with Task.create(task_params)
end
And I added:
#app/controllers/api/v1/tasks_controller.rb
private
...
def task_params
params.require(:task).permit(:name)
end

Saving a collection of objects rails 4 (strong params)

I am currently working on the backend of shop. The Client wants to be able to see a list of all products and update the stock values for all the products in one submission of a form. I have a working solution, but it's a very 'hacky' and introduces a lot of issues. I am new to Ruby on Rails and web development in general so I'm still learning a few of the fundamental conventions and what not.
I will paste my working solution and then attempt to explain the problem I have:
class Product < ActiveRecord::Base
has_many :stocks
...
end
class Stock < ActiveRecord::Base
belongs_to :product
...
end
stock_controller.rb
class StocksController < ApplicationController
def index
#products = Product.all.includes(:stocks)
end
...
def update_current
#stock_params = params[:stock]
#stock_params.each do |stock_params|
params.permit(:current_stock, :product_id)
#stock = Stock.new(stock_params)
#stock.save
end
redirect_to stocks_path, notice: 'Stocks were successfully updated'
end
...
stocks.index.html.erb
...
<%= form_tag url_for(:action => 'update_current') do |f| %>
<% #products.each do |product| %>
<tr>
<td><%= product.product_name %></td>
<td><%= product.minimum_stock %></td>
<td><%= text_field_tag "stock[][current_stock]", product.stocks.last.current_stock %></td>
<%= hidden_field_tag "stock[][product_id]", product.stocks.last.product_id %>
</tr>
<% end %>
<%= submit_tag 'save' %>
<% end %>
...
When I hit the submit button params set is as it needs to be:
console :
Started POST "/stocks/update_current" for 127.0.0.1 at 2013-10-24 11:54:03 +0100
Processing by StocksController#update_current as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"NlabBuwI06t+YN5O6p7dm+Zg2Bwc9uXrKUdWaBqNs9w=", "stock"=>[{"current_stock"=>"1", "product_id"=>"1"}, {"current_stock"=>"2", "product_id"=>"2"}, {"current_stock"=>"3", "product_id"=>"24"}, {"current_stock"=>"4", "product_id"=>"25"}, {"current_stock"=>"5", "product_id"=>"23"}, {"current_stock"=>"6", "product_id"=>"21"}, {"current_stock"=>"7", "product_id"=>"19"}, {"current_stock"=>"8", "product_id"=>"22"}, {"current_stock"=>"9", "product_id"=>"5"}], "commit"=>"save"}
Unpermitted parameters: utf8, authenticity_token, stock, commit
(0.2ms) BEGIN
SQL (136.6ms) INSERT INTO "stocks" ("created_at", "current_stock", "product_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00], ["current_stock", 1], ["product_id", 1], ["updated_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00]]
(24.2ms) COMMIT
Unpermitted parameters: utf8, authenticity_token, stock, commit
(0.2ms) BEGIN
SQL (0.7ms) INSERT INTO "stocks" ("created_at", "current_stock", "product_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00], ["current_stock", 2], ["product_id", 2], ["updated_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00]]
(0.7ms) COMMIT
Unpermitted parameters: utf8, authenticity_token, stock, commit
(0.1ms) BEGIN
SQL (0.4ms) INSERT INTO "stocks" ("created_at", "current_stock", "product_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00], ["current_stock", 3], ["product_id", 24], ["updated_at", Thu, 24 Oct 2013 10:54:03 UTC +00:00]]
(0.6ms) COMMIT
As you can see form the log the authenticity_token, and other params are unpermitted. Now I understand the purpose of the token and the other params, what I do not know, why exactly I am running into this issue.
My guess is the way I am permitting the params. I don't get how to tell strong_params to permit an array of hashes: stock => [{:current_stock, :product_id},{:current_stock, :product_id}, ..., ....]. params.permit(stock: [:current_stock, :product_id]) ???
It doesn't make sense in this case to nest stocks under product, as I am working with a collection of products opposed to a single product.
In an ideal world, I would like to be able to insert the new stock values for all products in one submit and save to the database with one query. I feel as if Ajax may be a viable solution, but again, until I fully understand whats going on I don't want to confuse things even more.
Any solutions or advice is much appreciated. I hope the above makes sense! It's very difficult to articulate these things sometimes.
This may or may not be your problem, but in your update_current method, shouldn't it be stock_params.permit(:current_stock, :product_id) ? Also a minor point, why do you have |f| in your form_tag if you don't use it.

How to save a serialized field

I'm trying to push values onto a serialized text field (acting as array).
In the controller I have
class DeliveriesController < ApplicationController
def new
#delivery = Delivery.new
end
def create
#user = current_user
#user.deliveries.create(params[:delivery])
#user.recent_addresses.shift if #user.recent_addresses.size >= 10
#user.recent_addresses.push(params[:delivery][:from_address])
#user.save
redirect_to root_path
end
end
User model
serialize :recent_addresses, Array
attr_accessible :recent_addresses
has_many :deliveries
The problem is that the user is not being saved with the new recent addresses. The from_address is being added within the controller but when I try save it rollsback and the recent addresses array is empty.
Parameters: {"delivery"=>{"from_address"=>"xyz"}, "commit"=>"Submit"}
SQL (0.6ms) INSERT INTO "deliveries" ("created_at", "from_address", "user_id") VALUES ($1, $2) RETURNING "id" [["created_at", Fri, 25 Oct 2013 13:21:50 UTC +00:00], ["from_address", "xyz"], ["user_id", 1]]
(0.8ms) COMMIT
(0.1ms) BEGIN
(0.2ms) ROLLBACK
Redirected to http://localhost:3000/

How do I pass commentable into mailer?

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.

CarrierWave. Impossible to save the file with STI

I have model Document:
class Document < ActiveRecord::Base
belongs_to :company
validates :name, :presence => true
end
And two classes inherited from Document:
License:
class License < Document
mount_uploader :file, DocumentUploader
end
And Certificate
class Certificate < Document
mount_uploader :file, DocumentUploader
end
And when I try to do current_company.licenses.create(...) or same action for the certificate, always all params are saved, besides file, which always is nil
Also I've tried to mount file inside of Document model... Help me please.
Here is logs:
Started POST "/companies/1/verified" for 127.0.0.1 at Mon Mar 19 09:33:41 +0200 2012
Processing by CompaniesController#verified as HTML
Parameters: {"verified"=>{"certificate"=>{"name"=>"Certificate", "file"=>"test.png"}, "insured"=>"2000000", "suppliers"=>"", "license"=>{"name"=>"License", "file"=>"test.png"}}, "authenticity_token"=>"0hIn41Tjonm/AXZBKM1PE/tjQxJDLqZaojMTHDoZq2k=", "id"=>"1", "utf8"=>"✓", "commit"=>"Update verifications"}
Company Load (0.7ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = 1 LIMIT 1
(0.1ms) BEGIN
SQL (0.8ms) INSERT INTO "documents" ("company_id", "created_at", "file", "name", "type", "updated_at", "verified") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["company_id", 1], ["created_at", Mon, 19 Mar 2012 07:33:41 UTC +00:00], ["file", nil], ["name", "License"], ["type", "License"], ["updated_at", Mon, 19 Mar 2012 07:33:41 UTC +00:00], ["verified", false]]
(0.6ms) COMMIT
(0.1ms) BEGIN
SQL (0.5ms) INSERT INTO "documents" ("company_id", "created_at", "file", "name", "type", "updated_at", "verified") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["company_id", 1], ["created_at", Mon, 19 Mar 2012 07:33:41 UTC +00:00], ["file", nil], ["name", "Certificate"], ["type", "Certificate"], ["updated_at", Mon, 19 Mar 2012 07:33:41 UTC +00:00], ["verified", false]]
(0.4ms) COMMIT
Redirected to http://localhost:3000/company/profile
Completed 302 Found in 18ms (ActiveRecord: 3.3ms)
Thanks.
Are you sure you've set the form that you've uploading the file with to have a multipart payload?
If not the file won't get sent on submission, and rails will only receive the textual form data. Inside the form_helper tag you'll need to add.
:html => {:multipart => true}

Resources