I have a Post model that have a title and content attributes.
I want to make it possible to tweet when the user creates a post like this.
<%= form_for #post do |f| %>
<%= f.text_field :title %>
<%= f.text_area :content %>
<%= f.check_box :with_tweet %> # Error
<%= f.text_field :tweet %> # Error
<% end %>
This code fails, because there are no with_tweet and tweet attributes for Post.
I don't think query strings are good idea situation like this.
How should I send a information that is not related a model?
Define them as virtual attributes:
class Post < ActiveRecord::Base
...
attr_accessor :with_tweet, :tweet
...
end
attr_accessor will provide a getter and a setter method for with_tweet and tweet which should then be accessible to you through the #post object.
Further to Vee's answer, let me explain why you'd need it:
Every attribute in a Rails model is the result of using a Ruby
getter & setter - meaning that your model's attributes are
essentially just parts of a Ruby object, built when your class is
initialized
The problem you have is Ruby on Rails does not build any other
attributes other than the ones in your DB, meaning if you wanted to
track extra data, you'll have to use virtual attributes to let
the class know to populate those not in the db
attr_accessor is used to define those extra attributes
Related
is a little project and I try to associate patient model with consultations. one patient has_many :consultations, in my form I have:
<%= f.association :patient %>
I pass the id parameter from the patient to the action 'new' in this way:
<%= link_to new_consultum_path(:id => #patient.id) %>
And in the view I have:
How can I make that the f.association field take the correspondent patient_id automatically?
How can I be sure that the patient_id is the current patient?
If I want to hide this field is that ok if I put
instead of
Is a better way to do this?
And why in the view shows me # patient:0x007f4e7c32cbd0 ?
thanks for your help.
And why in the view shows me # patient:0x007f4e7c32cbd0
This is a Patient object.
It means you need to call an attribute of this object - EG #patient.name.
--
f.association field take the correspondent patient_id automatically
This might help:
It looks like Organization model doesn't have any of these fields: [
:to_label, :name, :title, :to_s ] so SimpleForm can't detect a default
label and value methods for collection. I think you should pass it
manually.
#app/models/patient.rb
class Patient < ActiveRecord::Base
def to_label
"#{name}"
end
end
Apparently, you need to have either title, name or to_label methods in your model in order for f.association to populate the data.
-
How can I be sure that the patient_id is the current patient?
If you're having to verify this, it suggests inconsistencies with your code's structure. If you need the patient_id to be set as the current patient, surely you could set it in the controller:
#app/controllers/consultations_controller.rb
class ConultationsController < ApplicationController
def create
#consultation = Constultation.new
#consultation.patient = current_patient
#consultation.save
end
end
I can provide more context if required.
You want to associate consultations to patients using fields_for, which is similar to form_for, but does not build the form tags.
It you start with your patient object, you can iterate through the consultation associations binding it to form fields as you go.
it would look something like this
<%= form_for #patient do |patient_form| %>
<% patient_form.text_field :any_attribute_on_patient %>
<% #patient.consultations.each do |consultation| %>
<%= patient_form.fields_for consultation do |consultation_fields| %>
<% consultation_fields.text_field :any_attribute_on_consulatation %>
<% end %>
<% end %>
<% end %>
Sorry, the code may not be exactly right.
Check out the docs for field_for here
You will also have to set accepts_nested_attributes_for consultations on patient. When you set accepts_nested_forms_for, Rails will automatically update the associated consultations object to the patient and save any edits you have made. You DEFINITELY want to use accepts_nested_attributes_for most nested form handling of this type.
A quick warning: I am pretty new to Rails, and my knowledge is somewhat cookie-cutter-esque. I know how to do certain things, but I lack that vital understanding of why they always work.
I currently have a User model that has in it a bunch of information, like address, email, etc. In addition, it also has a hash called visible. The keys in that hash are each of the pieces of information, and the value is either true or false for whether the user wishes that information to be publicly visible. While I'm not sure if this is the best way to go, I can't think of any other way other than making a whole ton of boolean variables for each bit of information. Finally, I serialize :visible for storage in the database
What I would like is in my edit view to have a checkbox beside each field of info that represents the visible attribute. After reading tons of other posts related to this topic and trying numerous variations of code, I always end up with some kind of an error. The code that looks most intuitively correct to me is as follows:
<%= form_for(#user, :id => "form-info-personal") do |f| %>
...
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.check_box :visible[:name] %>
But I get an error message saying that a Symbol cannot be parsed into an integer. I'm not sure where this parse is even trying to happen, unless its viewing :visible as an array and trying to use :name as an index.
I apologize in advance if this question is trivial/seemingly nonsensical/lacking vital information/etc. Any tips, suggestions, links, or what have you would be very appreciated, even if they're along the lines of "you're doing this fundamentally wrong, go back and do it this way".
-Nick
Rails 3.2 introduces a nice addition to ActiveRecord, which allows you to store arbitrary settings in a single field.
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ]
end
u = User.new(color: 'black', homepage: '37signals.com')
u.color # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
So, your code could look like this:
# model
class User < ActiveRecord::Base
store :settings, accessors: [ :name_visible, :email_visible ]
end
# view
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.check_box :name_visible %>
I have a model with a corresponding form, for which I use ActiveRecord validations. At the bottom of the form I'd like to have a single confirmation checkbox which should not be persisted, but which must be checked for the form to be submitted. I'd also like any errors that stems from this checkbox not being checked to display alongside the ActiveRecord errors.
Now I could cobble something together in the controller manually, but I'm wondering if there is a built-in, cleaner way to handle this kind of situation?
I think you should add this in your model:
validates_acceptance_of :check_me
attr_accessor :check_me
attr_accessible :check_me # if you already have attr_accessible defined in your model
and this in your view:
<%= form_for #your_model do |f| %>
# some code
<%= f.check_box :check_me %>
<% end %>
I am new to Rails and am trying to set up my Models and was wondering how Rails handles associations.
I have a Quest object which "belongs_to" or references via foreign keys a number of other objects, including User and Content:
quest.user_id
quest.a_different_name_id #this is a foreign key to a Content object
these are both foreign keys referencing a User object and Content object respectively.
Both User and Content "has_many" Quests.
I understand that this setup allows me to do things like:
u = User.create #saves to database
u.quests.build #creates new Quest object with user id set to u.id
Can I do something in the opposite direction like:
form_for #quest do |f|
f.text_field :a_user_attribute #an attribute of a User object
f.text_field :a_different_name_attribute #an attribute of a Content object
where the form has text fields for the attributes of the objects which a Quest object references through its foreign keys as opposed to having a form for the actual foreign keys, so that when in the controller I have:
#quest = Quest.new(params[:quest])
Is Rails smart enough to "reach through" the model-defined foreign key relationships and populate and then save the User and Content objects and appropriately set the foreign keys in #quest to reference the newly created objects?
Can it do this even though the foreign key for the Content object has a different name than content_id?
Hope this makes sense... let me know if I am being unclear.
You can do what you need with the Nested Attributes feature in Rails http://guides.rubyonrails.org/2_3_release_notes.html#nested-attributes
Check out the form helper for it here
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
Basically you would need to do the following:
class User < ActiveRecord::Base
has_many :quests
accepts_nested_attributes_for :quests
...
end
class Quest < ActiveRecord::Base
belongs_to :user
...
end
then in the form you do the following:
<%= form_for #user do |f| %>
UserAttrA : <%= f.text_field :a_user_attribute_a %>
UserAttrB: <%= f.text_field :a_user_attribute_b %>
<%= f.fields_for :quests do |qf| %>
QuestAttrA : <%= qf.text_field :a_quest_attribute_a %>
QuestAttrB: <%= qf.text_field :a_quest_attribute_b %>
<% end %>
UserAttrC : <%= f.text_field :a_user_attribute_c %>
UserAttrD: <%= f.text_field :a_user_attribute_d %>
<% end %>
And your controller would work just like you have above.
Note that you can display User inputs before and/or after Quest inputs. Basically you can make the form in the view look how you want. But the semantics on the server will be need to be consistent.
When I use form_for :model the data is saved when I submit the form.
However when I use form_tag, the data is lost after the form is processed.
I need to use form_tag because I have two models in one form.
Is there a way to save form data with form_tag?
You are making two incorrect assumptions in your question. First, form_tag is not necessary or even recommended for multiple-model forms; Second, form_tag doesn't do anything fundamentally different from form_for, you are most likely not formatting the field names correctly for your controller.
In order to create a form with nested models, you need to use the fields_for helper in conjunction with form_for. The relationship needs to be defined first in the model with accepts_nested_attributes_for. Since you have not given us any information about your models, I will give you a made-up example:
class Person < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
belongs_to :person
end
This tells ActiveRecord that the Person model can accept attributes for Address, and will pass along the attributes to the correct model to be created.
<% form_for :person do |p| %>
<% p.fields_for :address do |a| %>
use the a form builder to create
fields for the address model here
<% end %>
<% end %>
chaining the fields_for helper from the p form builder lets the helpers generate attributes in the correct format.
More information: Nested Model Forms
Pretty much the same way as before except you'll need to build the params. You can look at your log to see how params are being sent.
eg.
def create
#silly_hat = SillyHat.new( :name => params[:name], :size => params[:size], :colour => params[:colour] )
if #silly_hat.save
...