Rails 4 How to load a has_many association to update - ruby-on-rails

I have a controller called Edit an existing client which does what the name implies. It will load up a client of that name and pull all relevant information if it exists. In the view I have
#client = Client.find_by(:id => 1)
and it loads all the information up correctly for anything that has_one association to Client. However for something like address which a Client has_many of, it does not show at all in the view. How would I fix this?
Example output
The address stuff should show up under number of dependents but it does not.
This is the view
And here is the table for addresses
Here is the controller for client
Here are the models
UPDATE Thank you bntzio. I am actually dumb. It is now pulling the types of addresses as it should, however the form allows you to add a former address and a mailing address. This is handled by a series of bools in the table. Right now it just pulls all three addresses and puts them under "Present Address". How would I add logic to pull the correct address for that section?
Sample output here

There are two things to consider here, the first one:
You should have a column for address in your database. Check your db migrations.
It should look like this:
t.string :address
If you don't have that table in your db, then you can't access that variable holding the address, so you need to add it with a migration.
rails g migration AddAddressToUsers address:string
or
rails g migration AddAddressToClients address:string (depending on how you have it).
Then do a migration to migrate the changes:
rake db:migrate
Reload your server and add the proper code in the view and it should be displayed correctly.
The second thing is:
Check your controller if it contains strong parameters, if yes, then add your :address variable (anyway you need to have that variable in your db, as mentioned before).

Related

Rails Cookies to manipulate database entries

I am trying to create a Rails app and I have a database consisting of author and a quotation by that author.
Now different users can choose to destroy or kill quotations from the database however it must only be deleted for that particular user i.e other users should still be able to see quotes that they didn't delete even if another user did.
I know that I would need to implement cookies but other than that I am unsure how to proceed. Can anyone point me to a tutorial or give me some pointers to get started on this complex task?
You surely have a User model in your application - one 'Rails-like' way to go about this would be to add a has_and_belongs_to_many relationship between User and Quotation.
This creates a relationship between each individual user and 'their' quotations. This relationship can be deleted without actually deleting a quotation, so all quotations would still be available to other users. If you want each user to be able to see all quotations by default, you would need to set up the relationship in advance.
Assuming you are using Devise to log your users in, all you'd need to do then is to replace Quotation.all with current_user.quotations in whichever controller you are using to display quotations.
The Rails guide linked above is quite helpful but basically you just need to add something like the following:
class User
has_and_belongs_to_many :quotations
before_create :add_quotations
def add_quotations
self.quotations << Quotation.all
end
#etc...
end
class Quotation
has_and_belongs_to_many :users
#etc...
end
and then run a migration adding a new table called users_quotations with the columns user_id and quotation_id.
EDIT
As #Yule pointed out this wouldn't let users see any quotations that were created after they were, and it would be quite annoying to have to set up the join tables in advance, so a more efficient way would be to have an excluded_quotations join table instead. So users can see all quotations except the ones that they have excluded.

Is dynamically changing Schema in Rails possible?

I would like to create new tables, add/delete columns from within my app. Is this possible?
Yes, you can do whatever the application database user can do to the database with ActiveRecord::Base.connection.execute. For example:
ActiveRecord::Base.connection.execute('ALTER TABLE people ADD name VARCHAR(60);')
But, if you add a column to a table, the corresponding attribute for the column will not be available in the ActiveRecord class until you restart the application.
No. It is not possible. Rails has to run migrations to get the tables in to the database. This requires that the server has be stopped and restarted after the migrations. You don't want this scenario in production.
Dynamic forms would accomplish what I believe you are after.
In short you make fields of a model a separate model. For instance
class Car
has_many :car_fields
end
class CarFields
belongs_to :car
end
Then you can make a form where the users can add and remove fields when the add a car to the database.
This is great explained by Ryan Bates here http://railscasts.com/episodes/403-dynamic-forms
I think you need a subscription to watch it. I you don't have one, get one. Railscasts is great!

Ruby on Rails - how to instantiate an empty model and populate the object

I am trying to create an empty model, populate it and then add it to the database.
I am looking through Google for the syntax for instantiating a simple model that I can set fields in, but there does not seem to be much documentation for that.
Is that just not the intended useage pattern? If it is, how can I just create the empty model?
Thanks!
An ActiveRecord model works based on what fields it's related table has in your db. If you have no db yet you have no fields. The usage pattern goes like this:
$ rails g model client name:string
#stuff happens
$ rake db:migrate
You now have a model associated with a clients table that has a string attribute called name.
Now in your controller you can use this by
#client = Client.new
#client.name = "foo"
#client.save
Which will create the model object, set the name, and persist it to the db
You should read up on the Rails Guides. Your current issue is covered at this link, but you really need to read up on getting started.

How Can I implement this in Rails?

I want to implement a feature where user can "add additional details" to his profile. Here he should be able to create the label for the detail and the actual details like:
Education : Degree
where Education is the label for the detail and Degree is the detail.
Apart from this, he should also have an option to decide whether this details should be made visible or hidden.
How can I implement this using a new model Profile with the association User has_one Profile.
If I just had Label and Text for the new details, I could have tried hash, but since I would also have to get the details from the user on whether the user wants the detail to be made hidden or visible, I might require an extra field to store that value (true or false).
I am really confused as to how I can get the whole thing implemented together.
Please suggest me how I can implement this and also how can I update the model each time a user creates a new detail without changing the schema of the db.
I am working on Rails 3.2.
I don't really see your problem (or I don't get it), but:
Why don't you just create a has_many AdditionalData with user_id:integer name:string content:string visible:boolean?
So you can loop through #user.additional_datas.visible (assuming you defined a scope scope :visible, where("visible = 1").
Added benefit: You could make this model polymorph and add additional information to other things you have in your app without the need to create an extra "information" table for every model you want to store these.
For validation, you could also add a data_type field and create validations according to the data type (needs to be an url, a phone number, just text, ...)
I don't see the problem too; I think an hash-like table could be the solution, something like this:
rails generate model UserDetails label:string value:string \
visible:boolean user:references
in which you put records like this:
user.details.create(:label => 'Dog name', :value => 'Fuffy' :visible => false)

custom properties in Rails

I have just started Rails and have a basic question.
I need to add customer properties(like email id etc) so that the Rails app can read them at runtime. How can I do this ?
Can I add them to development.rb and if so how can I read it ?
In java I would have created a properties file and read it from my app.
thank you,
firemonkey
Are you trying to do store and load configuration settings?
It's easy to store configuration settings in a yaml file and load them with initializers - loads better than littering your environment files.
This Railscast: http://railscasts.com/episodes/85-yaml-configuration-file shows you how.
I'm not sure exactly what you are asking. I'm guessing you want an initial set of data in the database that you can access when you actually run the app? If that is so check out this other SO question How (and whether) to populate rails application with initial data
It's a little unclear exactly what you're trying to do, but it sounds like maybe you have a model called Customer and you would like to add some attributes to it, such as email address, id, and so on?
Basically, with Active Record you don't need to do anything special to add a simple attribute (like a string or an integer). Just add a field called "email_address" to your customers table in the database, and all of your Customer objects will automagically get "email_address" and "email_address=" methods (not to mention the Customer class itself getting "find_by_email_address" and other useful methods as well). If you are adding a field containing another model, it's a bit more complicated - add a "something_id" field to the table, and an association to the class definition (eg, "has_one :something"). For more information, see the ActiveRecord api documentation.
You don't have to use any particular means to add the field to your database, but you might want to consider Migrations. Migrations are a convenient way to keep your schema versioned and synchronized across multiple machines.
If you are building your model right now, there's a short cut built in to the generator to add fields. Instead of just saying...
script/generate scaffold customer
...you can say...
script/generate scaffold customer email:string name:string badge_number:integer
...and it will generate all the appropriate fields in your migration, as well as adding them to your generated views.

Resources