undefined method `user_id' for #<ActiveRecord::Relation:0x007f8da82da248> - ruby

I am error in the 2nd line of the code here, I have a column user_id in the Estate table. What am I doing wrong here ?
myestate = Estate.where(:Mgmt => current_user.Company)
#managements = User.where(:id => myestate.user_id)

where is returning an ActiveRecord::Relation object. Because where(:mgmt => current_user.company) could return 0, 1, or Many records, you have to tell the query what you'd like from it.
Try:
myestate = Estate.where(:Mgmt => current_user.Company).first
#managements = User.where(:id => myestate.user_id)
Getting familiar with AREL and how it works is highly recommended. You can find great info on the github page or the Active Record Query Guide

Related

Is that good solution? [duplicate]

I have a record set that includes a date field, and want to determine how many unique dates are represented in the record set.
Something like:
Record.find(:all).date.unique.count
but of course, that doesn't seem to work.
This has changed slightly in rails 4 and above :distinct => true is now deprecated. Use:
Record.distinct.count('date')
Or if you want the date and the number:
Record.group(:date).distinct.count(:date)
What you're going for is the following SQL:
SELECT COUNT(DISTINCT date) FROM records
ActiveRecord has this built in:
Record.count('date', :distinct => true)
Outside of SQL:
Record.find(:all).group_by(&:date).count
ActiveSupport's Enumerable#group_by is indispensable.
the latest #count on rails source code only accept 1 parameter.
see: http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count
so I achieved the requirement by
Record.count('DISTINCT date')
Detailing the answer:
Post.create(:user_id => 1, :created_on => '2010-09-29')
Post.create(:user_id => 1, :created_on => '2010-09-29')
Post.create(:user_id => 2, :created_on => '2010-09-29')
Post.create(:user_id => null, :created_on => '2010-09-29')
Post.group(:created_on).count
# => {'2010-09-29' => 4}
Post.group(:created_on).count(:user_id)
# => {'2010-09-29' => 3}
Post.group(:created_on).count(:user_id, :distinct => true) # Rails <= 3
Post.group(:created_on).distinct.count(:user_id) # Rails = 4
# => {'2010-09-29' => 2}
As I mentioned here, in Rails 4, using (...).uniq.count(:user_id) as mentioned in other answers (for this question and elsewhere on SO) will actually lead to an extra DISTINCT being in the query:
SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...
What we actually have to do is use a SQL string ourselves:
(...).count("DISTINCT user_id")
Which gives us:
SELECT COUNT(DISTINCT user_id) FROM ...
Also, make sure you have an index on the field in your db, or else that query will quickly become sloooow.
(It's much better to do this in SQL, otherwise you pull the entire db table into memory just to answer the count.)

Return new id with DB::insert() in Laravel 4

In Laravel 4, when you perform a DB::insert(), how can you get the ID of the row that has just been inserted? Similar what we have with the function ->insertGetId(). Reason for using DB::insert() is that its a complex PostgreSQL query that cannot be built using Fluent.
Example Query:
$newId = DB::insert('insert into users (id, name) values (?, ?)', array(1, 'Dayle'));
echo $newId; // returns 1
There is a insertGetId method.
$id = DB::table('users')->insertGetId(
array('id' => 1, 'name' => 'Dayle Rees')
);
If you take a look at Illuminate\Database\ConnectionInterface you can see how these functions are written. Unfortunately DB::insert() returns a boolean from PDOStatement::execute() and there is no DB::insertGetId() at the moment. If this would be useful then you should request it on GitHub.
In the mean time, you should be able to use DB::getPdo()->lastInsertId()
There is a insertGetId() method, as follows:
$dataset = array('column_id' => 1, 'name' => 'Dayle');
$column_id = DB::table('users')->insertGetId($dataset,'column_id');
A bit late with the answer but, I think for psql it's best to use native RETURNING id
The query that worked for me was:
DB::select(
DB::raw('insert into threads (created_at, updated_at) values (?, ?)
returning id'), [Carbon::now(), Carbon::now()]
);
If you get in complex structure, better to use Eloquent.
Best thing that you need review docs :
http://laravel.com/docs/eloquent
After saving the data into the DB you just call $insertedId = $user->id; where $user->save() is called before the step.
more info here

How to update multiple columns in Ruby on Rails 3?

Just out of curiosity, is there a way to say this...
user.update_column(:field1, true)
user.update_column(:field2, true)
... in one line in Ruby on Rails?
As far as I know an update_columns method does not exist...
You can use update_all as follows:
User.where(:id => user.id).update_all({:field1 => true, :field2 => true})
This will generate the following update statement (mysql):
UPDATE users SET field1 = 1, field2 = 1 WHERE users.id = <whatever>
Callbacks and validations will not be run.
Note: this is only available in ActiveRecord v4.0.2 and higher:
You can do in this way:
update_columns(field1: value, filed2: value)
what about doing it like this:
user.attributes = attributes
user.save(validate: false)
If you need speed you can also call execute directly on AR connection. I used something like this to import large amount of data.
connection = ActiveRecord::Base.connection
email = connection.quote(email)
zip = connection.quote(zip)
connection.execute(%{UPDATE "users" SET "email" = #{email}, "zip" = #{zip} WHERE "users"."id" = #{user.id}})
Note that validations and callbacks will not be run.
Copied from https://stackoverflow.com/a/25171127/1520775

How to use Magentor gem

I am trying to use the Magentor gem. The documentation is very weak. I succeeded in calling Magento::Category.info(1).
But I failed to call Magento::Category.create(args).
The method definition is like the following.
# catalog_category.create
# Create new category and return its id.
#
# Return: int
#
# Arguments:
#
# int $parentId - ID of parent category
# array $categoryData - category data ( array(’attribute_code’⇒‘attribute_value’ )
# mixed $storeView - store view ID or code (optional)
def create(attributes)
id = commit("create", attributes)
record = new(attributes)
record.id = id
record
end
Here's what I tried.(parent id is 1)
args = [1, {:name => 'Cars', :description => 'Great Cars', :is_active => '1', :url_key => 'cars'}]
category_id = Magento::Category.create(args)
exception: 1 -> SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
Can anybody provide an example of calling the method?
I contacted the gem developer and got the following reply. A nice guy.
Hi Sam,
Sorry about the sparse documentation. We had created this library very quickly and only used a small subset of the api in the project we were working on.
It looks like the call for create in the library does not pass through data correctly. Here is a workaround:
parent_id = 1
attributes = {
:url_key=>"cars",
:description=>"Great Cars",
:name=>"Cars",
:is_active=>"1",
:available_sort_by => "Name",
:default_sort_by => "Name",
:include_in_menu => '1'
}
category_id = Magento::Category.commit("create", parent_id, attributes)
I'll also commit a fix to github that takes the parent_id correctly.
Thanks,
-preston

Rails 3 getting wrong count in query

I'm trying to get the number of messages that haven't been read.
The Message model has a column called read_at. If the message has been read there is a value in read_at, if it's unread then that value is nil.
I have one read message and one unread message. I get 0 unread messages (I should be getting 1). This is the code:
Message.all(:conditions =>
['website_id = ? AND read_at = ?', current_website.id, nil]).count
It seems that the query is right, since the development log is showing me
Message Load (0.2ms) SELECT "messages".* FROM "messages"
WHERE (website_id = 2 AND read_at = NULL)
instead of read_at = NULL
try read_at is null, it is a SQL thing.
:conditions => ['website_id = ? AND read_at is ?', current_website.id, nil]
Here is a short article on SQL nulls, and how to use them:
http://www.w3schools.com/sql/sql_null_values.asp
Hope it helps
Though the problem is the one pointed by #pdjota, you should use Rails 3 notation, here is how I would write it:
Message.where('website_id = ? AND read_at IS NULL', current_website.id).count

Resources