Edit user from another view? - ruby-on-rails

I need to edit a user's data from another view. Example, when a user makes a new post, they can change their name, phone number, address, etc. I am using the Devise gem.
Does anyone have any ideas?

You can edit any model/migration from any view. Rails doesn't restrict you on that, though it does try to lead you down the conventional way. In the view you want to edit your user, try something like this:
<%= form_for #user do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
...more code here...
<% end %>
Just make sure that #user is a user object.

Related

Form for each user

I have an ordinary form to create a Package object at /packages/new:
<%= form_for #package do |f| %>
<%= f.text_field :name %>
<%= f.text_field :address %>
...
<% end %>
The package model belongs_to :partner.
I am looking for a way to associate a new package form to a specific partner, preferably without any input from the user filling it in.
For example, if partner A sends a link to the form, I want the form to include partner_id:A.id.
How can I connect forms to partners?
You can send partner_id param with the link which your partner will send.
Something like
http://website.com/packages/new?partner_id=3
And use the param as hidden_field in the form
<%= form_for #package do |f| %>
<%= f.text_field :name %>
<%= f.text_field :address %>
<%= f.hidden_field :partner_id, value: params[:partner_id] %>
...
<% end %>
Alternatively you can also make use of Nested Resources
you can have, hidden field which passes partner_id to controller
http://apidock.com/rails/ActionView/Helpers/FormHelper/hidden_field
If the partner needs to be logged in, in order to create a package, you could simply link the package to the partner in the controller right before saving it.
As mentioned before, use params. And don't forget to allow the required params in the controller if necessary (via link, scroll down a little). documentation: params
Check out what e.g. .build() does for you. more about relations and how to set them up correctly

Storing user input value in controller

I have a controller named Welcome with view called index.
In my index view i have created a small form as such.
<%= form_for :location do |f| %>
<%= f.label :Longitude %><br>
<%= f.text_field :integer %>
<br>
<br>
<%= f.label :Latitude %><br>
<%= f.text_field :integer %>
<p>
<%= f.submit %>
</p>
<% end %>
In this form the user can enter some integer value for longitude and latitude. Once the user enters value for longitude and latitude. They click submit. Upon submit i would like to store these values in my controller. So i am using the following method where i have two instance variables taking values from the form.
def index
#long = params[:longitude]
#lat = params[:latitude]
end
In my routes.rb I have
get 'welcome/index'
post 'welcome/index'
Please tell me where i went wrong. Also if someone can suggest a better way of doing this also i would appreciate it i am new to rails and i want to learn the correct way of doing things so i don't create bad habits early on.
The reason it's not working is because your fields are both named :integer, and since they share the same name, the browser will only send one value.
So, with your code, if you filled in the first field with 'a' and the second with 'b', your params would contain something like this:
{ location: { integer: "aaa" } }
Which obviously isn't what you want! If your HTML looked more like this (I've stripped the layout stuff to make things clearer):
<%= form_for :location do |f| %>
<%= f.label :longitude %>
<%= f.text_field :longitude %>
<%= f.label :latitude %>
<%= f.text_field :latitude %>
<%= f.submit %>
<% end %>
Then you could access the params in your controller params[:location][:longitude] and params[:location][:latitude]
A good idea to see the difference between the effect of your form vs this form would be to inspect the html. Take a look at the input name attributes, and label for attributes and see how they match up with the params Rails receives. Also, when you post the form, be sure to look in your server log to see the params! :)
After reading your question, I think you want to see how controllers, views and models work. For learning purpose you can generate scaffold and study the generated code.
For example, generate a model GeoLocation, related controller and views by this:
rails g scaffold GeoLocation longitude:string latitude:string
Now fire up rails server and browse http://localhost:3000/geo_locations/new and save your long, lat. I wrote this answer to give you some guidance.
You can follow these excellent books:
The book of Ruby
The Rails 4 Way

Mentioning user username in comments (#mention) - Rails

In my rails app, if a user mentions another username in a comment by using the # character, such as #max i'm trying to add autocomplete to suggest a list of users and then automatically create a link_to (username, user_path(user)
This is what I have in my comment partial:
<%= form_for [commentable, Comment.new] do |f| %>
<%= hidden_field_tag :commentable_type, commentable.class.to_s %>
<%= hidden_field_tag :commentable_id, commentable.id %>
<p>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
I'm trying to use this gem: https://github.com/ichord/jquery-atwho-rails
It says to bind the text area with
data = ['tom','john'];
$('textarea').atwho({at:"#", 'data':data});
Where do I actually put this? Can I do something like data = User.all? Should I just be using a regular expression to do this?
I think the reason that data = User.all isn't working is because User.all will return an array of User objects. What you want to do is retrieve those User object usernames (or whatever you want the autocomplete to use, and store that in data instead.
You might try something like
#usernames = User.pluck(:username)
to get all the usernames. Then, in your partial:
data = <% #usernames &>
$('textarea').atwho({at:"#", 'data':data});
This is assuming of course that your partial is an .erb file where you can embed ruby code.
You can do something like this:
<script>
data = <%= raw User.pluck(:username).compact.to_json %>;
$('textarea').atwho({at:"#", 'data':data});
</script>
You might want to move the loading of the usernames into the controller or a helper method. The whole sniplet might belong into an view partial to keep things organized. And it might not be the best idea to load all usernames into the view when there are too many users in the database.

Rails 3 -- Pass user.id in hidden form field vs using association

Ok so currently I have a form
<div class="field">
<%= f.label :title %><br/>
<%= f.text_field :title %><br/>
<%= f.label :itunesurl %><br />
<%= f.text_field :itunesurl %><br />
<%= f.hidden_field :user_id, :value => current_user.id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
Which passes the current_user.id into the create method of my "app" model which creates it like this before saving it:
#app = App.new(params[:app])
However I have associations of (pseudocode)
user has_many apps
apps belongs_to user
Question: is it safer (so the form doesn't get modified) to do something like this within the create method?
#user = current_user
#app = #user.apps.create(params[:app])
If so... how exactly would I go about actually implementing the code above (its not syntactically correct.. just pseudo)?
Thanks!
Yes using the second way that you have suggested is the best approach
#user = current_user
#app = #user.apps.create(params[:app])
Also make sure you protect yourself from mass assignment, take a read of this http://stephensclafani.com/2010/01/04/ruby-on-rails-secure-mass-assignment/
It's absolutely safer to do it the second way. If you do it the first way, you're trusting the client to state who they are. Anyone could easily modify the form (with firebug, or they could manually submit a POST request with many tools) and end up submitting a form with the current_user of another person.
Make sure you apply this thinking everywhere throughout your app. Do not trust anything the client submits, ever.
The second code snippet is more "RESTful" than the first. By more RESTful, I mean, if an App is a resource that is logically accessed through a User, then by all means use it.
The way you set that up through routes:
resources :users do
resources :apps
end
This will give you paths like user_app_path and new_user_app_path, to which you pass a user ID and an app ID or a new app.
Hope this helps

how to handle multiple models in a rails form

http://weblog.rubyonrails.org/2009/1/26/nested-model-forms
This post helped in learning how to handle multiple models in a rails form. It works as long as the models are nested. what if they are not? lets say, I have a form, where the user fills personal details, address details and a bunch of checkboxes specifying her interests. There are at least 3 tables involved in this one single form, what is the best way to handle this, without having 3 different save buttons?
Two options:
First is ActivePresenter which works well for this.
Second is just to use fields_for:
<%= form_for #user do |f| %>
<%=f.label :name %>
<%=f.text_field :name %>
<%= fields_for #address do |fa| %>
<%=fa.label :city %>
<%=fa.text_field :city %>
<% end %>
<% end %>
Then in the controller, save the records.
#user = User.new(params[:user])
#address = Address.new(params[:address])
ActivePresenter works so well though.
Also found a railsforum post via Google, which would work well.
You can refer this tutorial by The Pragmatic Programmers
Advanced Rails Recipes

Resources