Ruby - Set foreign key from global variable - ruby-on-rails

I have 2 models called worequest and status.
worequests has_many statuses and status belongs to worequest.
The statuses table has a foreign key called worequest_id.
If someone is looking at a worequest, I want to allow them to create a new status record.
So, I created a button on the worequest show page. I thought that I would save the worequest.id in a global variable like this and link to create the new status record:
<% $current_request = #worequest.id %>
<%= link_to 'New Status', new_status_path, :class => 'btn btn-primary' %>
Then in the new status page, I have this code:
<% if $current_request == nil %>
<%= f.input :worequest_id, :label => 'Request ID' %>
<% else %>
<% f.text_field :worequest_id, :value => $current_request %>
<% $current_request = nil %>
<% end %>
But, the worequest.id field in the status record ends up being nil.
I also tried:
<% f.input :worequest_id, :value => $current_request %>
Any ideas?

You should just use sessions.
session[:worequest_id] = #worequest.id
Then when you get to the other page, just call the value back and put it in.
f.hidden :worequest_id, :value => session[:worequest_id]

Thanks Mizuho.
I used the session idea:
<%= f.hidden_field :worequest_id, :value => session[:worequest_id] %>
Before your comment, I didn't have the = after the <%. Once I put it in, it worked.

Related

How to make a link_to that redirects and submits a form

I have a modal that will serve as a disclaimer in my app and I need the link at the bottom of the modal that says "agree & continue" to toggle a boolean and input the time that the boolean was toggled. I have created the button as a form with hidden links but I cant seem to see how to make it submit the form AND redirect to the path i specify. Here is my link_to code now.
<% if current_user.user_record.blank? %>
<%= form_for :user do |f| %>
<% f.hidden_field :disclosure_acceptance, :value => true %>
<% f.hidden_field :disclosure_date, :value => Time.now %>
<%= link_to("Agree & Continue", user_steps_path(current_user), class: "btn btn-primary") %>
<% end %>
<% end %>
First, create a new method in your user_records_controller or at whichever controller action the form is displayed at:
def new
#user_record = current_user.build_user_record
end
Put this in your view:
<% if current_user.user_record.blank? %>
<%= form_for #user_record do |f| %>
<%= f.hidden_field :disclosure_acceptance, :value => true %>
<%= f.hidden_field :disclosure_date, :value => Time.now %>
<%=f.submit "Agree & Continue", class: "btn btn-primary") %>
<% end %>
<% end %>
Make a create action for the user_record that looks like this:
def create
#user_record = current_user.build_user_record(permitted_params)
if #user_record.save
redirect_to user_steps_path(current_user)
else
render :new
end
end
private
def permitted_params
params.require(:user_record).permit(:disclosure_acceptance , :disclosure_date) #etc
end
UPDATE
If you directly want to jump to the 'create' action, you can make your configuration like this:
Add a custom action to your routes:
post 'rate/:article_id' => 'user_records#create' :as => :create_user_record
#or whichever controller/action you wish
You should update the route on your form:
= form_tag create_user_record_path, :method=>'post' do
#etc
In order to create a user_record from the controller, you need to change things a little bit:
def create
current_user.user_record.create(:user_id => current_user.id, :disclosure_acceptance => params[:disclosure_acceptance] , :disclosure_date => params[:disclosure_date])
if current_user.user_record.save
#etc
end

Adding or updating record with user id

Ruby on Rails 3, I have an edit page with two select_tag submissions. One has users that have the attribute :attend = "Yes" and the other has users that have the attribute :attend = "No" or nil. I am trying to get the select_tag submissions to create or update the Certificate table for the user. As of now I know it is POSTing the user id and name. I do not know how to get the controller or model to take the user id and create or update with the :attend attribute value of "Yes" or "No". The app will create a new record with the correct user id but not with :attend since it is not in my select_tag submission.
Here is my edit:
<%= form_for #untrained do |f| %>
<p> Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#current_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Un-Train", class: "btn btn-large btn-primary" %>
<% end %>
<%= form_for #trained do |f| %>
<p> Non-Trained Users </p>
<%= select_tag "certificate[user_id]", options_for_select(#non_trained.collect{|x| [x.name, x.id]}), {:multiple => :multiple} %>
<%= f.submit "Trained", class: "btn btn-large btn-primary" %>
<% end %>
Here is my controller:
#trained = Certificate.new(params[:certificate])
#untrained = Certificate.update(params[:user_id])
Here is my model:
attr_accessible :attend, :pass, :user_id
belongs_to :user
validates :user_id, presence: true
How do you set the controller to create or update a new record with :attend as "Yes"?
How do you update the record with :attend as "No"?
Thank you
Have u tried in the controller after
if #trained.save
put
#trained.update_attributes(attend: "yes")
or no depending on the type u want.
Also have a look at this for the create/update method in rails.
create_or_update method in rails

Rails check_box_tag within form_for

Is it possible to pass the value of checked check_box_tags within a form_for in Rails inside a hash?
Here is a very generic, basic version of the form:
<%= form_for(:object, :url => { :action => 'create', :id => params[:id]}) do |f| %>
<p>Field_a: <%= f.text_field(:field_a) %></p>
<p>Field_b: <%= f.text_field(:field_b) %></p>
<p>Field_c: <%= f.text_field(:field_c) %></p>
<p>Check boxes:</p>
<% check_box_choices_object_array.each do |s| %>
<%= check_box_tag(s.name, 1, false) %>
<%= .name %><br />
<% end %>
<%= submit_tag("Create") %>
<% end %>
Outputs roughly:
Field_a ___________________
Field_b ___________________
Field_c ___________________
Check boxes:
[] box_a
[] box_b
[] box_c
[] box_d
[] box_e
[] box_f
[] box_g
My problem is that since the available check boxes aren't actual fields in the object's table in the database (i.e. I'm not using check_box(:field) in the form), each checked check box gets passed as an individual parameter (i.e. "box_a" => "1", "box_b" => "1", "box_e" => "1"). I would like them to be passed as such:
:checked_boxes => {"box_a" => "1", "box_b" => "1", "box_e" => "1"}
This way, I can access them easily with params[:checked_boxes].
How do I do this, or, better yet, is there a better solution (I'm new to rails)?
I think you'd get the results you want if you wrap the checkboxes iterator in a fields_for :checked_boxes tag - or at least get you close to the results you want.
<%= form_for(:object, :url => { :action => 'create', :id => params[:id]}) do |f| %>
<p>Field_a: <%= f.text_field(:field_a) %></p>
<p>Field_b: <%= f.text_field(:field_b) %></p>
<p>Field_c: <%= f.text_field(:field_c) %></p>
<p>Check boxes:</p>
<%= f.fields_for :checked_boxes do |cb| %>
<% check_box_choices_object_array.each do |s| %>
<%= cb.check_box(s.name, 1, false) %>
<%= .name %><br />
<% end %>
<% end %>
<%= submit_tag("Create") %>
<% end %>
you can deal with no database attributes and models using attr_accessor
class Thing < ActiveRecord::Base
attr_accessible :name
attr_accessor :box_a, :box_b, :box_c
end
This way you can call these attributes in your form.

ActionMailer delivery when following parameters met

Forgive me for asking what i believe is quite an in depth challenge (well for me at the moment anyway)
I have a small app that allows users to check in, check out and hopefully receive emails when a book has been checked back in by registering their interest via a remind me button
So far I have setup actionmailer (basic setup)
class ReminderMailer < ActionMailer::Base
default from: "email address"
def remind_email(book)
#book = book
#url = "http://localhost:3000"
mail(:to => #book.user.email, :subject => "Book Reminder")
end
I have all the config in place to send the emails as I am already doing that through devise.
I have also created the mailer templates. It is the logic I am stuck with.
So when a User checks a book out i pass this back to the model
<%= form_for #book do |f| %>
<%= f.label :checked_out, "Check Book Out?" %>
<%= f.check_box :checked_out, {}, true %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :checked_out, :value => true %>
<%= f.submit 'Checkout' %>
<% end %>
Check In
<%= form_for #book do |f| %>
<%= f.label :checked_out, "Check Book Back In" %>
<%= f.check_box :checked_out, {checked: false}, false %>
<%= f.hidden_field :user_id, :value => nil %>
<%= f.hidden_field :checked_out, :value => false %>
<%= f.submit 'Check In' %>
<% end %>
Register Interest
<%= form_for #book do |f| %>
<%= f.label :remind_me, "let Me know when book back in" %>
<%= f.check_box :remind_me, {checked: false}, false %>
<%= f.hidden_field :remind_me, :value => current_user.id %>
<%= f.submit 'Remind Me' %>
<% end %>
So my thinking is that when you register your interest your user id gets placed into the remind_me column, and what i want to achieve is that when the checked_out field is false and book.user_id is back to nil I would like the email to send the the user whos user_id is in the remind_me column
Am i thinking about this in the correct way?
if anyone can help it would be appreciated so that i can learn from this and then keep practicing it until I understand what is going on
There are 2 ways to answer:
The first one, don't use a form to check in a book and just call a method. For example: You replace your form with a link which call a new method in your controller:
<%= link_to "check in", check_in_book_path(#book.id) %>
In your books_controller you call a model method which check in the book:
def check_in
#book = Book.find params[:id]
#book.check_in!
redirect_to book_path(#book)
end
In your book model:
def check_in!
self.user = nil
self.checked_out = false
if self.save
RemindMailer.remind_mail(self).deliver
end
end
Don't forget to add the route for your new controller method.
The second way, if you keep your form, is shorter but more complicated. You need to add a callback to your model which will verify if the data changed. For example, in you book model:
after_save :send_mail_if_check_in
def send_mail_if_check_in
if !self.checked_out && self.changes[:user_id] && self.user.nil?
RemindMailer.remind_mail(self).deliver
end
end
I prefer the first solution because it seems to be a state machine which is more maintenable.
I hope this help

Two records with two different layouts/views in one create

Ok, here my Problem:
i have a tabel in a radius-system. to enable a hotspot-user i need two different records in this table.
the record has the fields user, attr, op, value
first record: attribute has to be Password (this record is only for the password here) and value is the password itself.
second record: attribute has to be something like Max-Allowed-Session an value is an integer in seconds.
So i add this as nested attributes to my controller clients. In new i do that:
def new
#client = Client.new
2.times do
radcheck = #client.radchecks.build
end`
respond to........
end`
Ok, in my view i have this at the moment:
f.fields for :radchecks do |rcbuilder|
<p><%= rcbuilder.label :username %><br /><%= rcbuilder.text_field :username %>
for all fields .....
end
In my controller i built two radchecks, so this part is shown two times.
That is status, but i wanna have something like this in my website
<first occurence of that form>
<%= rcbuilder.hidden_field :attr, :value => "password" %>
<%= rcbuilder.hidden_field :value, :value => #generated_password %>
<end first occurence>
<second occurence of that form>
<%= rcbuilder.hidden_field :attr, :value => "Max-Allowed-Session" %>
<%= rcbuilder.label :value, 'Time in hours' %><%= rcbuilder.text_field :value %>
<end second occurence>
Somone has an idea to realize that. Maybe i have to write the indexed fields myself, but how can i achieve that?
thanks for help....
Assuming you are using accepts_nested_attributes_for :radchecks in your Client model.
<% index=1 %>
f.fields for :radchecks do |rcbuilder|
<%= render :partial=>'radcheck_fields', :locals=>{:rcbuilder=>rcbuilder, :index=>index}%>
<% index+=1 %>
end
Next create a partial named radcheck_fields.html.erb with the following code.
<% if index.eql?(1) %>
<%= rcbuilder.hidden_field :attr, :value => "password" %>
<%= rcbuilder.hidden_field :value, :value => #generated_password %>
<% else %>
<%= rcbuilder.hidden_field :attr, :value => "Max-Allowed-Session" %>
<%= rcbuilder.label :value, 'Time in hours' %><%= rcbuilder.text_field :value %>
<% end %>

Resources