Ruby on rails "undefined method" error - ruby-on-rails

When I try to run the following code on a form I get the following error message:
undefined method `store_ID' for # <Store:0x007f98ec2a1d68>
I checked the model, controller, and schema but the store_ID is consistent with the other working parameters. How do I "define" it first?
<%= simple_form_for(#store) do |f| %>
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence
if f.object.errors[:base].present? %>
<div class="form-inputs">
<%= f.input :location, required: true %>
<%= f.input :branch_manager, required: true %>
<%= f.input :store_ID, required: true %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Here are my schema.rb
create_table "stores", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.string "location"
t.string "branch_manager"
t.integer "store_ID"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

I think you have not run the migrations according to what you say
"I added the ID field after generating everything, so I do not know if that makes the difference"
With this you should solve:
rails db:migrate

Related

Using a Hidden Field inside a Rails 5 Partial to Save an Array

I am trying to do the seemingly innocuous task of passing an array of tags to a new subscriber form, based on which page it's rendered on.
My Subscriber table looks like this in schema.rb:
create_table "subscribers", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "phone"
t.string "email"
t.text "tags", default: [], array: true
t.text "admin_notes"
t.boolean "unsubscribe"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
My partial is rendered like this:
<%= render partial: "layouts/new_subscriber", locals: { tags: "buyer, LM-house-tour-checklist" } %>
Which brings up this _new_subscriber.html.erb partial:
<%= simple_form_for(#new_subscriber) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.label :first_name %>
<%= f.text_field :first_name, required: true, class: "form-control" %>
<%= f.label :last_name %>
<%= f.text_field :last_name, required: true, class: "form-control" %>
<%= f.label :phone %>
<%= f.text_field :phone, required: true, class: "form-control" %>
<%= f.label :email %>
<%= f.text_field :email, required: true, class: "form-control" %>
<%= f.hidden_field :tags, value: tags %>
</div>
<div class="form-actions text-center">
<%= f.submit "Get My Checklist", class: "btn" %>
</div>
<% end %>
I have tested using the Chrome code inspector that "buyer, LM-house-tour-checklist" is getting passed into the hidden field value.
However, when I submit, it creates the subscriber with a :tags attribute of ["uyer"]. This is super weird and unexplainable to me.
Some other info:
There is nothing in my subscriber model.
#new_subscriber is defined in my ApplicationController using before_action :new_subscriber and def new_subscriber #new_subscriber = Subscriber.new end
I have tried the method described here, but to no avail
Can anyone help me do this in the "Railsiest" way possible? It dosn't seem like that unusual of an ask, but I can't get it to work properly.
Maybe because it's sent as string.
Try to add attr_accessor :plain_tags in model
Instead of tags field use this attribute.
And in before_create callback write something like
before_create :populate_tags
def populate_tags
return if self.tags_plain.blank?
self.tags = self.tags_plain.split(",")
end

Ruby on Rails: Saving form check boxes to Boolean in Postgres

Rails noob here, how do I get a Rails form to save a boolean checkbox to postgres? I've tried dozens of things I've found online and none of it is working. No matter what I do, the entry in the Postgres DB is "Null". Here is my
Model(schema):
ActiveRecord::Schema.define(version: 20171227200151) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "notes", force: :cascade do |t|
t.string "note_title"
t.string "note_text"
t.boolean "note_scratch", default: false, null: false
t.boolean "note_info"
t.boolean "note_reminder"
t.boolean "note_task"
t.string "note_tags"
t.date "note_remind_date"
t.time "note_remind_time"
t.integer "note_archived"
t.date "note_archived_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
view:
<%= form_with scope: :note, url: notes_path, local: true do |f| %>
<p>
<%= f.label :note_title %><br>
<%= f.text_field :note_title %>
</p>
<p>
<%= f.label :note_text %><br>
<%= f.text_area :note_text %>
</p>
<p>
<%= f.label :notes_scratch, "Scratch" %>
<%= f.check_box :notes_scratch %>
<%= f.label :notes_info, "Info" %>
<%= f.check_box :notes_info %>
<%= f.label :notes_reminder, "Reminder" %>
<%= f.check_box :notes_reminder %>
<%= f.label :notes_task, "Task" %>
<%= f.check_box :notes_task %>
</p>
<p>
<%= f.label :note_tags %><br>
<%= f.text_field :note_tags %>
</p>
<p>
<%= f.label :note_remind_date %><br>
<%= f.date_field :note_remind_date %>
</p>
<p>
<%= f.label :note_remind_time %><br>
<%= f.time_field :note_remind_time %>
</p>
<%= f.submit %>
<% end %>
Controller:
class NotesController < ApplicationController
def new
end
def create
# for testing
# render plain: params[:note].inspect
#note = Note.new(note_params)
#note.save
redirect_to #note
end
private
def note_params
params.require(:note).permit(:note_title, :note_text, :note_scratch, :note_info, :note_reminder, :note_task, :note_tags, :note_remind_date, :note_remind_time, :note_archived, :note_archived_date)
end
end
If I just render the form results, it will show checked boxes as 1s, but it always comes up Null in the database, even if I set the datatype to Integer (hoping it would store the 1). All of the other fields record just fine. It's only the checkboxes that don't work.
I appreciate any assistance you can lend!
-Brick
Review your note_params (and schema.rb):
def note_params
params.require(:note).permit(:note_title, :note_text, :note_scratch, :note_info, :note_reminder, :note_task, :note_tags, :note_remind_date, :note_remind_time, :note_archived, :note_archived_date)
end
In your view: notes_* needs to be singular as your schema is note_*.

how to add button that would pass and store current time in database in rails 5?

should js be used to perform the action or is there any other method to do so?
This is my attendance table.
create_table "attendances", force: :cascade do |t|
t.datetime "intime"
t.datetime "outtime"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
This is my code:
<div class="field">
<%= f.label :intime %>
<%= f.datetime_select :intime %>
</div>
<div class="field">
<%= f.label :outtime %>
<%= f.datetime_select :outtime %>
</div>
<div class="actions">
<%= f.submit %>
</div>
Follow the following steps:
1. Create two buttons InTime & OutTime in the form which will submit the user_id & time_type(intime or outtype) as a parameter.
2. Create a function in the controller which will receive the above paramters & save the intime or outtime like intime = Time.now , save the record.
3. Create the routes for the above controller.

Rails many to many model with select in the view

The logic in the exercise is create a Bill where a Bill have a list of Products with an amount of them.
I have the next 3 models:
Bill
Product
BillItem (This is the intermediate model between Bill and Product for the many to many relationship)
Schema for more clarity:
create_table "bill_items", force: :cascade do |t|
t.integer "amount"
t.integer "product_id"
t.integer "bill_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["bill_id"], name: "index_bill_items_on_bill_id"
t.index ["product_id"], name: "index_bill_items_on_product_id"
end
create_table "bills", force: :cascade do |t|
t.string "user_name"
t.string "dni"
t.date "expiration"
t.float "sub_total"
t.float "grand_total"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "description"
t.float "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
First i have a list of created products in my database.
For my BillController i have a _form.html.erb where i want be capable to create dynamic selects for choose a product and set a amount.
My view is the next:
<%= form_for bill do |f| %>
<div>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
</div>
<div>
<%= f.label :dni %>
<%= f.text_field :dni %>
</div>
<div>
<%= f.label :product %>
<%= f.collection_select :product_ids, Product.all, :id, :name %>
</div>
# Here i should add more selects if the user want to add more products.
<div><%= f.submit %></div>
<% end %>
My problem or my question is: how to "groupe" the ids of the products and the amount of them. And the another question is, i can create the other selects dynamically with JS?
You need to be adding multiple BillItem to your form to account for the amount and the product. This is done through accepts_nested_attributes_for on the model. For example:
class Bill < ActiveRecord::Base
has_many :bill_items
accepts_nested_attributes_for :bill_items
end
Initialize a BillItem on the Bill in your controller:
class BillsController < ActionController::Base
def new
#bill = Bill.new
#bill.bill_items.build
end
end
Then in your form, use the fields_for helper to create sub-forms:
<%= form_for #bill do |f| %>
<div>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
</div>
<div>
<%= f.label :dni %>
<%= f.text_field :dni %>
</div>
<%= f.fields_for :bill_items do |f| %>
<div>
<%= f.label :product %>
<%= f.collection_select :product_id, Product.all, :id, :name %>
</div>
<div>
<%= f.label :amount %>
<%= f.number_field :amount %>
</div>
<% end %>
<%= f.submit %></div>
<% end %>
And yes, you can use javascript to create new nested forms.

Rails shows non existent database records

Rails shows that an instance of the Comment model exists, even though the database is empty. My code to show the Comment is
<% #post.comments.each do |c| %>
<%= c %>
<% end %>
And from that, I get #<Comment:0x007fe971c02800> also if i do c.attributes I get
{"id"=>nil, "body"=>nil, "author"=>nil, "post_id"=>37, "deleted"=>nil, "locked"=>nil, "created_at"=>nil, "updated_at"=>nil}, but the table has no records. If I change that code to
<% #post.comments.each do |c| %>
<%= c.body %>
<% end %>
I get nothing.
Maybe it has something to me using closure_tree.
If it helps, here is the schema for the table:
create_table "comment_hierarchies", id: false, force: true do |t|
t.integer "ancestor_id", null: false
t.integer "descendant_id", null: false
t.integer "generations", null: false
end
add_index "comment_hierarchies", ["ancestor_id", "descendant_id", "generations"], name: "comment_anc_desc_udx", unique: true
add_index "comment_hierarchies", ["descendant_id"], name: "comment_desc_idx"
create_table "comments", force: true do |t|
t.string "body"
t.string "author"
t.string "post_id"
t.boolean "deleted"
t.boolean "locked"
t.datetime "created_at"
t.datetime "updated_at"
end
EDIT: I fixed it by changing the form on the page to make a new comment from
<%= form_for([#post, #post.comments.build], :html => {:class => 'ui form'}) do |f| %>
<div class="field">
<%= f.text_area :body, placeholder: "Comment", style: "max-height: 100px;"%>
</div>
<p>
<%= f.submit "Add Comment", class: "blue ui button" %>
</p>
<% end %>
to
<%= form_for([#post, Comment.new], :html => {:class => 'ui form'}) do |f| %>
<div class="field">
<%= f.text_area :body, placeholder: "Comment", style: "max-height: 100px;"%>
</div>
<p>
<%= f.submit "Add Comment", class: "blue ui button" %>
</p>
<% end %>
Could you be calling #post.comments.new somewhere before this to render the comment form? This could be adding the new, non-persisted record in the association_cache.
To avoid this, you should be able to instantiate the comment as Comment.new(post_id: #post.id). This shouldn't add the comment to the association_cache. If it does, you really don't need the post_id on the new Comment. You probably have it in a hidden field anyway.
It seems like there is a comment persisted in your database for this post.
c.body may return nil, it alone doesn't define that there is no comment record in your database. Maybe you had no validation or manually skipped it on the console a while ago.
c.inspect will give you a more verbose breakdown of what data is in the object.
How are you confirming your database is empty? Does #post.comments.count equal 0?

Resources