I'm having difficulties getting an association to work with simple_form.
I have the following models.
class Product < ActiveRecord::Base
belongs_to :Retailer
end
and
class Retailer < ActiveRecord::Base
has_many :Products
end
My form partial (products/_form.html.erb) contains the following
<%= simple_form_for(#product) do |f| %>
...
<% f.input :currency %>
<% f.association :retailer %>
...
It works without the association, but with it I get the following error:
undefined method `retailer_id' for #<Product:0x007ffbe0f7d530>
I'm (obviously) quite new to this, but haven't been able to work this out.
edit: checked I'd run migrations and they are up-to-date. The Retailer table has an id column!
> Retailer.all
Retailer Load (0.2ms) SELECT "retailers".* FROM "retailers"
=> [#<Retailer id: 1, name: "Retailer 1" etc...
chema file:
ActiveRecord::Schema.define(:version => 20120308195055) do
create_table "alerts", :force => true do |t|
t.string "url", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "products", :force => true do |t|
t.string "title", :null => false
t.integer "price_cents", :default => 0, :null => false
t.string "currency", :null => false
t.string "asin", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "retailers", :force => true do |t|
t.string "name", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
Since you have belongs_to :Retailer and <% f.association :retailer %> in your model and form for Product respectively, you'll need to add a retailer_id column to your products table.
You are missing t.references :retailer in your migration file for creating products table.
That is why, I quote you "it works without the association, but with it the error is undefined method 'retailer_id' for #<Product:0x007ffbe0f7d530>"
Yes, the retailers table has an id column but in order to reference a retailer from a product, your products table requires a retailer_id column.
Related
I have a joined table but looking for a way to input the information from a form into both tables, or have it work in general:
My schema:
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "categories_listings", id: false, force: :cascade do |t|
t.integer "category_id", null: false
t.integer "listing_id", null: false
end
create_table "listings", force: :cascade do |t|
t.string "name"
t.text "description"
t.decimal "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image"
t.integer "user_id"
end
Models:
class Category < ApplicationRecord
has_and_belongs_to_many :listings
end
Listing < ApplicationRecord
belongs_to :category, required: false
belongs_to :categories_listings, required: false
end
Views
<%= form_with(model: listing, local: true) do |form| %>
...
<div class="space">
<%= form.select :category_ids, options_from_collection_for_select(Category.all, :id, :name), :prompt => "Select a Category", :multiple => true %>
</div>
...
Before i joined the tables, I had it working with a categories element (i believe thats the right term) within the listing tables that was attached to a categories table... You can see my previous post on SO where I was suggested to do this: Allowing multiple records in category to submit to listing
When i click submit, nothing enters into the categories_listings tables. Suggestions on how I make this happen?
The associations in your Listing model are wrong. It should be just
Listing < ApplicationRecord
has_and_belongs_to_many :categories
end
I suggest you to read has_and_belongs_to_many
When viewing a user's Show page, I Would like to display the teams the user is on followed by the number of members on each team. I am trying to understand how to write methods in the model for this functionality to happen.
class Membership < ActiveRecord::Base
attr_accessible :team_id, :user_id
belongs_to :team
belongs_to :user
end
class Team < ActiveRecord::Base
attr_accessible :name, :user_id
belongs_to :admin, :class_name => "User",:foreign_key => "user_id"
has_many :memberships
has_many :members, through: :memberships, source: :user
has_many :users, through: :memberships
end
class User < ActiveRecord::Base
belongs_to :team
has_many :teams, through: :memberships
has_many :memberships
end
ActiveRecord::Schema.define(:version => 20140211214838) do
create_table "memberships", :force => true do |t|
t.integer "team_id"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "teams", :force => true do |t|
t.string "name"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", :default => 0, :null => false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "username"
t.string "bio"
t.string "location"
end
end
You have the associations in place, you just need to iterate over the teams in the view. E.g something like:
# users/show.html.erb
...
<% #user.teams.each do |team| %>
<div><%= "#{team.name} (#{team.members.count})" %></div>
<% end %>
...
Depending on what else you're doing with the teams and members data, for performance reasons it may be a good idea to eager load some of the associations with the user.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I have a small app going that lets 'Employees' check in and check out 'Items' by virtue of 'Transactions'. Those are the models in play. I'm having a hard time showing the items that are CURRENTLY checked out - and while I've read about scopes I'm having a hard time getting the associations, scopes, and views to work. I'm pulling my hair out - and I'm new to rails, so please be gentle.
I'm not too worried about performance with this app, and I know that nested conditionals within views are a terrible thing, and I know that I should be using partials, but this is really just for an MVP.
db/schema.rb
ActiveRecord::Schema.define(:version => 20130516162824) do
create_table "employees", :force => true do |t|
t.string "phone"
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "items", :force => true do |t|
t.string "description"
t.string "assettag"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "transactions", :force => true do |t|
t.boolean "status"
t.integer "item_id"
t.integer "employee_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "transactions", ["employee_id"], :name => "index_transactions_on_employee_id"
add_index "transactions", ["item_id"], :name => "index_transactions_on_item_id"
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false
t.string "encrypted_password", :default => "", :null => false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", :default => 0
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
end
models/employee.rb
class Employee < ActiveRecord::Base
attr_accessible :name, :phone
has_many :transactions
has_many :items, :through => :transactions
end
models/item.rb
class Item < ActiveRecord::Base
attr_accessible :assettag, :description
has_many :transactions
has_many :employees, :through => :transactions
scope :checked_out, -> { last_transaction.checkout }
end
models/transaction.rb
class Transaction < ActiveRecord::Base
attr_accessible :employee_id, :item_id, :status
belongs_to :employee
belongs_to :item
delegate :phone, :name, to: :employee
delegate :description, :assettag, to: :item
scope :last_transaction, -> { order('created_at DESC').limit(1) }
scope :checkin, where(:status => true)
scope :checkout, where(:status => false)
end
app/views/employees/show.html.erb
<% if #employee.items.checked_out %>
<h3>Currently Checked-OUT Items</h3>
<table>
<tr>
<th>Item ID</th>
<th style="padding-left:30px">Asset Tag</th>
</tr>
<% #employee.transactions.items.checked_out.reverse.each do |transaction| %>
<tr>
<td style="padding-left:30px">
<%= transaction.description %>
</td>
<td style="padding-left:30px">
<%= transaction.assettag %>
</td>
</tr>
<% end %>
</table>
<% end %>
The problem is that you want the employee's items, but the field that supplies the condition is on the model in between the items and conditions. One way is to add some more associations to your employee model.
class Employee < AR::Base
has_many :current_transactions, :conditions => { :status => CHECKED_OUT }
has_many :checked_out_items, :through => :current_transactions
end
last_transaction is defiend on transaction which is is why you get the no method error. That scope should be
scope :checked_out, -> { transactions.last_transaction.checkout }
if you want all the transactions then remove last_transactions scope
scope :checked_out, -> { transactions.checkout }
I have 3 tables- OwnerofProperty , Property and Ticket. I want to make a form using form_for to represent property booking; can I make a form to retrieve data from Property where the submit button saves the data in the Ticket table? I am asking because I have no idea if that can be possible or how to make it.
Note: I have only created the relations :
OwnerofProperty one-to-many Property
Property one-to-one Ticket
I need this form just to make a user able to see the avaliable properties and can book only one , how to make this form ?
Schema.rb for the three models :
create_table "owners", :force => true do |t|
t.string "f_name"
t.string "l_name"
t.string "address"
t.string "tel_no"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "properties", :force => true do |t|
t.string "p_street"
t.string "p_city"
t.string "postcode"
t.string "property_type"
t.integer "rooms"
t.integer "rent"
t.integer "owner_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "properties", ["owner_id"], :name => "index_properties_on_owner_id"
create_table "tickets", :force => true do |t|
t.string "city"
t.string "street"
t.string "ticket_type"
t.integer "rooms"
t.integer "rent"
t.integer "property_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "tickets", ["property_id"], :name => "index_tickets_on_property_id"
Yes, it is possible.
let's see ticket_controller.rb
def new
#property = Property.find 20 #20 is property id
#properties = Property.all
##ticket = Ticket.new
end
now in view (where you want to create form):
<%= form_for #ticket do |f| %>
<%= f.select :property_id, #properties.collect {|p| [ p.name, p.id ] }%> <!-- just an example, Ticket model has a field named "property_id" -->
<%= f.submit %>
<%= end %>
this form submits to create action of ticket_controller. And you are able to get all data as params and save it to table.
def create
#ticket = Ticket.new(params[:ticket])
#ticket.save
respond_to do |format|
format.html{redirect_to( your_desired_path)}
end
end
I've got a really weird problem with my project. I've got 2 models, the one is Link and the other Category. I've got a index view where all the links should be listed, together with the corresponding category names. When running the server and trying to use
<%= link.category.name %>
I get an error page with the following:
undefined method `name' for nil:NilClass
But when I open the console and write:
link = Link.find(1) #there is currently only one link
link.category.name
It returns the correct category name.
Here are my Models and schema.rb:
class Link < ActiveRecord::Base
attr_accessible :category_id, :description, :title, :url, :visible
belongs_to :category
scope :visible, lambda { where(visible: true) }
end
.
class Category < ActiveRecord::Base
attr_accessible :name
has_many :links
end
.
ActiveRecord::Schema.define(:version => 20130420070717) do
create_table "categories", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "categories", ["id"], :name => "index_categories_on_id"
create_table "links", :force => true do |t|
t.string "title"
t.text "description"
t.string "url"
t.integer "category_id"
t.boolean "visible"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "links", ["category_id"], :name => "index_links_on_category_id"
add_index "links", ["id"], :name => "index_links_on_id"
end
How can this happen? Thank you very much for your help!
Maybe I can help others facing the same issue.
The category_id was assigned to the link by a form which queries the existing categories from the db.
<%= f.select(:category_id, #categories.collect { |c| c.name }) %>
The category I wanted to assign has the id = 1. After selecting the category from the dropdown menu, the link.category_id was 0, it should have been 1.
UPDATE:
I fixed the wrong index by:
<%= f.collection_select :category_id, #categories, :id, :name, :prompt => "Select a category" %>