I wonder, is there an easier way to do the following
#controller's action
#my_model = MyModel.create field1: params[:field1],
field2: params[:field2],
field3: params[:field3],
field4: params[:field4]
# and so on.....
I would use
#my_model = MyModel.create params
but would it work since params always contains other keys added by Rails?
P.S.
The same question for updating a model (would this work properly?)
MyModel.update_attributes params
Send params as a nested hash like
{:my_model => {:field1 => 'blah', :field2 => 'blah'}, :controller => 'something', :action => 'something_else'}
This way you could just say
#my_model = MyModel.create params[:my_model]
Rails does this automatically if you have followed the conventions while creating the form.
Related
In my form:
<%= f.select :user, User.all %>
This generates a select with a collection of all users.
When I hit submit, it's currently passing the object as a string, looks like below:
[3] pry(#<PermissionFormsController>)> params[:permission_form][:user]
=> "John Doe <John.Doe#foo.com> - Bar (something)"
and
[4] pry(#<PermissionFormsController>)> params[:permission_form][:user].class
=> String
I'd like to get the object rather, like current_user
[5] pry(#<PermissionFormsController>)> current_user
=> Homer Simpson <homer#gmail.com> - Foo (admin)
Which is an object of class User:
[6] pry(#<PermissionFormsController>)> current_user.class
=> User(id: integer, status: string, ...)
Is there a way to achieve this?
You cannot pass Ruby objects directly from a form to the server, only strings. Your controller is responsible for turning this data into actual models. This is normally done by passing the object id and calling YourModel.find in the controller.
So you need to change your form like this:
<%= f.select :user_id, User.all.map{|u| [u.to_s, u.id]} %>
And then in your controller's action:
user = User.find(params[:permission_form][:user_id])
Hope this helps.
Im trying to update all post where a condition is true. If the condition is true should the field category_id be set to params[:category_id]
Every time im trying to do it will my code update all post where the condition is true and set it to "--- !ruby/hash:ActionController::Parameters categori_id: '169'"
Instead of just 169.
My controller action look like this
def update_all_notes
#deletefolder = Categori.find(params[:id])
System.where(:categori_id => params[:id]).update_all(:categori_id => params[:categori_id])
redirect_to :back
end
My form look like this:
<%= form_tag update_all_notes_path(category.id) do %>
<%= collection_select :kategori_id, :id, #current_company.category.where.not(:name => category.name), :id, :name %>
<button>move</button>
this is the parameters i send to the action
"categori_id"=>{"categori_id"=>"169"},
"id"=>"168"}
Thanks in advance
From your hash you should replace params[:categori_id] to be params[:categori_id][:categori_id]
as the hash is { "categori_id" => {"categori_id" => 169}, "id" => X }
Example of update_all use:
ids = [1,2,3]
records = Mammal::Human.where(id: ids)
records.update_all(status: :enlightenment, enlightenment_at: Time.zone.now, enlightenment_by: "myself")
I will rather use status: value over :status => value syntax
Is it possible to pass a list of objects to another controller in Ruby on Rails?
I have experimented with the following example:
class Student
...
end
student_list = [std1, std2, ... stdn]
When I use
<%= link_to_remote("example", :url => {:controller => 'class/assignment',
:action => 'homework',
:student => student_list})%>
It did not work the way I expected. params[:student] is equal to "student" (string literal).
Is there anything I did wrong, or an alternate way of doing it?
I'm still on the rather steep side of the Rails learning curve, so please pardon the rather simplistic nature of this question, but Google's just not proving very helpful.
So, my issue is this. I have a controller that is calling a mailer. (Code snippet below)
The problem I can't seem to get passed is that no matter how I try to access the values in the rhtml page, I either get errors or nothing at all.
This is the controller snippet (#person is working just fine. #item is what's not working)
if params[:id] == 'username'
item_value = #user[:login]
elsif params[:id] == 'password'
item_value = #user[:new_password]
end
#item = { 'name' => params[:id], 'val' => item_value }
ApplicantMailer.deliver_forgot(#person.email, #person, #item)
This is the mailer method snippet:
def forgot(recipient, person, item, sent_at = Time.now)
#subject = 'Site Password Retrieval'
#body['person'] = person
#body['item'] = item
#recipients = 'rdavis#localhost'
#from = CONTACT_EMAIL
#sent_on = sent_at
#headers = {}
logger.debug #body.to_yaml
end
This is the rhtml snippet:
Dear <%= #person.first_name %>,
You are receiving this email because you or someone else has used the lost <%= #item[:name] %> page from the login page.
Your <%= #item[:name] %> for your account is: <%= #item[:val] %>
So, like I said, when I try to access the values for the #item, if I use #item.name it throws a missing method error and if I use the version listed above, it doesn't show anything.
I know I'm working with a hash & thought that trying to access the keys like I showed here was the right way. Obviously, I'm missing something here.
Can someone point me in the right direction, please? Thanks!
You are using strings when creating your hash and symbols when accessing it.
You want the following:
#item = { :name => params[:id], :val => item_value }
Which is distinct from:
#item = { 'name' => params[:id], 'val' => item_value }
You can try this in irb with the following.
hash = {"a" => "val1", :a => "val2", "b" => "val3"}
hash["a"] => "val1"
hash[:a] => "val2"
hash["b"] => "val3"
hash[:b] => nil
Something I've always wondered about rails is the ability to pass extra data to find_or_create methods in rails. For example, I can't do the following
User.find_or_create_by_name('ceilingfish', :email => 'an_email#a.domain', :legs => true, :face => false)
I could do
u = User.find_or_create_by_name('ceilingfish')
u.update_attributes(:email => 'an_email#a.domain', :legs => true, :face => false)
But that's uglier, and also requires three queries. I suppose I could do
User.find_or_create_by_name_and_email_and_face_and_legs('ceilingfish','an_email#a.domain',true, false)
But that kind of implies that I know what the values of email, legs and face are. Does anyone know if there's a really elegant way of doing this?
Try this:
User.find_or_create_by_name(:name=>'ceilingfish',
:email => 'an_email#a.domain', :legs => true, :face => false)
When you have additional parameters to find_or_create_by_, you have to pass all the parameters as a hash.
Rails 4
User.create_with(
email: 'an_email#a.domain',
legs: true, face:false
).find_or_create_by(:name=>'ceilingfish')
With rails 4.x
DEPRECATION WARNING: This dynamic method is deprecated. Please use e.g. Post.find_or_create_by(name: 'foo') instead
Use this
User.find_or_create_by(first_name: 'Scarlett') do |user|
user.last_name = 'Johansson'
end